我們知道spring容器會提前暴露剛彎沉構造器注入但未完成其他步驟(如setter注入)的bean,通過提前暴露一個單例工廠方法,從而使其他bean可以引用到該bean,這樣可以解決單例作用域在setter注入循環依賴的問題,但是在測試過程中,缺出現了棧溢出的問題:
通過xml配置簡單配置兩個bean:
@Data
public class TestA {
private TestB testB;
}
@Data
public class TestB {
private TestA testA;
}
<bean id="testA" class="pres.zj.testspring.TestA">
<property name="testB" ref="testB"></property>
</bean>
<bean id="testB" class="pres.zj.testspring.TestB">
<property name="testA" ref="testA"></property>
</bean>
測試:
public static void main(String[] args) {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("bean.xml", MyTest.class));
TestA testA = (TestA) beanFactory.getBean("testA");
System.out.println(testA.hashCode());
System.out.println(testA.getTestB().getTestA().hashCode());
}
結果出現異常:
Exception in thread "main" java.lang.StackOverflowError
at pres.zj.testspring.TestB.hashCode(TestB.java:9)
at pres.zj.testspring.TestA.hashCode(TestA.java:9)
at pres.zj.testspring.TestB.hashCode(TestB.java:9)
at pres.zj.testspring.TestA.hashCode(TestA.java:9)
其實原因就出在@data註解上,通過反編譯文件,看到lombok重寫的hashcode方法:
public int hashCode() {
int PRIME = true;
int result = 1;
Object $testB = this.getTestB();
int result = result * 59 + ($testB == null ? 43 : $testB.hashCode());
return result;
}
TestA在計算hashcode時候調用了TestB類的hashcode方法,同理,TestB在計算hashcode的時候又調用了TestA的hashcode方法,於是便無限遞歸了。
解決方法:使用@Setter和@Getter代替@Data