正常Java中循环依赖场景
// A依赖了B
class A {
B b;
}
// B依赖了A
class B {
A a;
}
// new A(); 时,A中关联的B值为null
// new B(); 时,B中关联的A值为null
但在Spring中使用@Autowired注解标签进行自动注入时,如不加以处理,就会出现循环依赖的问题:
创建A bean对象 --> 需要注入B bean对象 --> 创建B bean对象 --> 需要注入A bean对象
Spring中如何解决循环依赖问题
Spring内部有三个map存储不同阶段的对象(三级缓存)
一级缓存(singletonObjects):放的是初始化完成的bean
二级缓存(earlySingletonObjects):放的是没有初始化完成的
三级缓存(singletonFactories):放的是用来创建初始化某个bean的工厂对象
过程解析:
1.初始化 BeanA,需要注入 BeanB,去查找,BeanB,没有找到,把 BeanA 交给一个工厂对象,将 BeanA 工厂对象存入到三级缓存中。
2.去查找 BeanB,BeanB 不存在,也将 BeanB 交给一个工厂对象,将 BeanB 工厂对象也存入到三级缓存中。
3.由于 BeanB 需要 BeanA,此时可以在第三级缓存中找到 BeanA 工对象,注入给BeanB,然后将 BeanB 放入到二级缓存,从三级缓存中删除 BeanB 工厂对象,注入到 BeanB,完成 BeanB 的初始化,放入到一级缓存。
4.当 BeanB 完成初始化后,将完整的 BeanB 注入到 BeanA 中,完成 BeanA 的初始化。