官网说明
官网意思是说,循环依赖出现的场景是构造器注入。例如:类A通过构造函数注入需要类B的实例,类B通过构造函数注入需要类A的实例。如果为类A和类B配置bean以相互注入,Spring IoC容器将在运行时检测此循环引用,并抛出BeanCurrentlyIncrementationException。bean a和bean B之间的循环依赖迫使一个bean在完全初始化之前注入另一个bean(典型的鸡和蛋场景)。下面会详细从代码层面讲解怎么Spring人怎么检测处循环依赖的异常。
A,类B两个类相互依赖图如下
代码如下
@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,正常报错。
分析异常
-
从getBean(“beanName”)的开始
-
首先将beanName放入一个集合中,如果集合中存在beanName,则抛出BeanCurrentlyInCreationException(beanName)
-
继续初始化bean
-
1 如果该bean依赖(这里指构造器注入)另一个bean s ,那么回到getBean(“s”)
3.2 完成bean的初始化
- 从集合中删除beanName
所以类A,B的分析如下:
创建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