在使用Spring时,若是主要采用基于构造器
的依赖注入方式,则可能会遇到循环依赖的状况,简而言之就是Bean A
的构造器依赖于Bean B
,Bean B
的构造器又依赖于Bean A
。在这种状况下Spring会在编译时抛出BeanCurrentlyInCreationException
。java
@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); } }
@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 B
,Class B
实例化完成后开始设值,而这时Class A
已是实例化完成了的,因此能够成功引用到Class A
。测试