Circular dependency
Definition: Circular dependency is a circular reference, which means two or more Beans hold each other, for example, CircularityA refers to CircularityB, CircularityB refers to CircularityC, and CircularityC refers to CircularityA. Form a circular reference relationship.
When using Spring, if you mainly use the constructor-based dependency injection method, you may encounter circular dependencies. In short, the Bean A's constructor depends on Bean B, and the Bean B's constructor depends on Bean A. In this case Spring will throw a BeanCurrentlyInCreationException at compile time.
Class A
@Componentpublic 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
@Componentpublic 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); }}test
@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(); }}reason
At this time, you will find that a BeanCurrentlyInCreationException exception is thrown. The reason for this is that when Spring creates a bean, it will instantiate the object first and then inject the dependency. Suppose Spring creates Class A first, then it will find that there is a Class B dependency in the constructor, so it will turn to create Class B, and then find the dependency on Class A in the constructor of Class B. At this time, Class A has not been initialized, so it will turn to create Class A, which will fall into a dead loop.
Solution
Switching to setter-based dependency injection can solve this problem. Because setter-based dependency injection will first call the default constructor to instantiate the object, and then call setter to implement dependency injection. In this way, there is no dependency in the instantiation stage of object. Therefore, after Class A is instantiated, Class B is called, and after Class B is instantiated, it starts setting values. At this time, Class A is already instantiated, so it can successfully refer to Class A.
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.