Spring中的循环依赖

循环依赖

在使用Spring时,若是主要采用基于构造器的依赖注入方式,则可能会遇到循环依赖的状况,简而言之就是Bean A的构造器依赖于Bean BBean B的构造器又依赖于Bean A。在这种状况下Spring会在编译时抛出BeanCurrentlyInCreationExceptionjava

Class A

@Component
public class ClassA {
    private ClassB classB;

    @Autowired
    public ClassA(ClassB classB) {
        this.classB = classB;
    }

    public void printClass() {
        System.out.println("Class A = " + this);
        System.out.println("Class B = " + classB);
    }
}

Class B

@Component
public class ClassB {
    private ClassA classA;

    @Autowired
    public ClassB(ClassA classA) {
        this.classA = classA;
    }

    public void printClass() {
        System.out.println("Class A = " + classA);
        System.out.println("Class B = " + this);
    }
}

测试

@ContextConfiguration(classes = {ClassA.class, ClassB.class})
@RunWith(SpringRunner.class)
public class MyTest {
    @Autowired
    private ClassA classA;
    @Autowired
    private ClassB classB;

    @Test
    public void name() {
        classA.printClass();
        classB.printClass();
    }
}

缘由

这时候运行测试就会发现抛出了BeanCurrentlyInCreationException异常。产生这种状况的缘由是,Spring在建立Bean时,会首先实例化对象,而后再注入依赖。假设Spring首先建立Class A,那么就会发如今构造器里有Class B的依赖,因此就会转去建立Class B,又在Class B的构造器里发现了对Class A的依赖,而此时Class A是还未初始化完的,所以又会转去建立Class A,这样就陷入了死循环。函数

解决方法

换成基于setter的依赖注入便可解决这个问题。由于基于setter的依赖注入会首先调用默认构造函数来实例化对象,而后再调用setter实现依赖注入。这样在对象实例化的阶段就没有了任何依赖,所以Class A实例化完成后再调用Class BClass B实例化完成后开始设值,而这时Class A已是实例化完成了的,因此能够成功引用到Class A测试

相关文章
相关标签/搜索