Spring循环依赖的流程

官网说明

博客索引

官网循环依赖

image.png

官网意思是说,循环依赖出现的场景是构造器注入。例如:类A通过构造函数注入需要类B的实例,类B通过构造函数注入需要类A的实例。如果为类A和类B配置bean以相互注入,Spring IoC容器将在运行时检测此循环引用,并抛出BeanCurrentlyIncrementationException。bean a和bean B之间的循环依赖迫使一个bean在完全初始化之前注入另一个bean(典型的鸡和蛋场景)。下面会详细从代码层面讲解怎么Spring人怎么检测处循环依赖的异常。

A,类B两个类相互依赖图如下

image.png

代码如下


@Component

public class B {

private A a;

public B(A a) {

this.a = a;

}

}

复制代码

@Component

public class A {


private B b;


public A(B b) {

this.b = b;

}

}

复制代码

创建一个启动类ComponentBootStrap


@Configuration

@ComponentScan

public class ComponentBootStrap {

public static void main(String[] args) {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComponentBootStrap.class);

}
}

复制代码

启动,nice,正常报错。

image.png

分析异常

  1. 从getBean(“beanName”)的开始

  2. 首先将beanName放入一个集合中,如果集合中存在beanName,则抛出BeanCurrentlyInCreationException(beanName)

  3. 继续初始化bean

  4. 1 如果该bean依赖(这里指构造器注入)另一个bean s ,那么回到getBean(“s”)

3.2 完成bean的初始化

  1. 从集合中删除beanName

所以类A,B的分析如下:

image.png

创建bean之前放入集合中。代码如下

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);

}

}

复制代码

public BeanCurrentlyInCreationException(String beanName) {

super(beanName,

"Requested bean is currently in creation: Is there an unresolvable circular reference?");

}

复制代码

如何解决

官网也说过,改成setter注入即可。原理的话,下期再讲。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享