循环依赖问题
A、B都是spring容器中的bean,A中有一个属性是B【A依赖于B】,B同样依赖于A。就会出现循环依赖问题。
构造器注入循环依赖:
public A(B b){
this.b = b;
}
public B(A a){
this.a = a;
}
Spring没有解决
set注入循环依赖:
@Component
public class A {
@Autowired
privare B b;
}
@Component
public class B {
@Autowired
privare A a;
}
Spring解决了
循环依赖解决办法
三级缓存
1、创建A,发现需要B。创建B,发现需要A,这个时候就出现了循环依赖
2、getBean(a):创建A ---> 先把创建出A的对象 ---> 构造一个A代理对象的工厂的对象放入到三级缓存
3、getBean(b):A需要注入B ---> 容器中没有B,去创建B ---> 逐层从一级缓存开始查找,直到三级缓存为止 ---> 先创建B的对象,放入二级缓存 ---> 发现需要A,则去获取A的时候,发现在三级缓存中有创建A对象的工厂,于是使用工厂创建A对象。将创建出的A对象放入到二级缓存,移除三级缓存的工厂对象。---> B需要A【但A现在是一个有地址但不完整的对象,可以赋值了】,于是B就完全初始化成功成一个完整的Bean,把B放入到一级缓存。
4、回到A调用getBean(b)的方法,继续造A,A再从一级缓存去获取B,有 ----> A也初始化成一个完成的bean ---> 那么把二级缓存的A放入到一缓存,删除二级缓存中的A
但是一般来说,我们会选择手动避免循环依赖问题,比如A需要B的一个方法【A依赖于B】,B也需要A的一个方法,此时就可以创建一个C来放A的那个被B需要的方法,最后就是A依赖于B,B依赖于C,就不会出现循环依赖的问题了。