我们知道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