Website shows

Blog index

Official website loop dependency

The official website says that the scenario in which loop dependencies occur is constructor injection. For example, class A uses the constructor to inject instances that need class B, and class B uses the constructor to inject instances that need class A. If for class A and class B configuration bean by mutual injection, the Spring IoC container will detect the circular reference at runtime, and throw BeanCurrentlyIncrementationException. A cyclic dependency between Beans A and B forces one bean to inject another bean before it is fully initialized (a typical chicken and egg scenario). The following sections explain in more detail how Spring people detect loop-dependent exceptions at the code level.

The interdependence diagram of class A and class B is as follows

The following code

@Component public class B { private A a; public B(A a) { this.a = a; }}Copy the code
@Component public class A { private B b; public A(B b) { this.b = b; }}Copy the code

Create a bootstrap class ComponentBootStrap

@Configuration @ComponentScan public class ComponentBootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComponentBootStrap.class); }}Copy the code

Start, nice, normal error.

Analysis of abnormal

  1. Start with getBean(“beanName”)

  2. Will first beanName into a collection, if beanName exist in the collection, it throws BeanCurrentlyInCreationException (beanName)

  3. Continue initializing the bean

  4. 1 If the bean depends on another bean s, go back to getBean(“s”)

3.2 Complete the bean initialization

  1. Removes beanName from the collection

So the analysis of class A and B is as follows:

Put the bean into the collection before creating it. The following code

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation

protected void beforeSingletonCreation(String beanName) { if (! this.inCreationCheckExclusions.contains(beanName) && ! this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }}Copy the code
public BeanCurrentlyInCreationException(String beanName) { super(beanName, "Requested bean is currently in creation: Is there an unresolvable circular reference?" ); }Copy the code

How to solve

And it says on the official website, you can do setter injection. I’ll talk about that in the next video.