Lombok使用@Data注解当循环依赖时调用hashcode导致StackOverflowError栈溢出的问题

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章