吃透Spring源码(十三):Spring循环依赖源码分析
一,循环依赖
1,什么是循环依赖
循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。
在Spring中一般分为构造器循环依赖和filed属性循环依赖。
2,构造器循环依赖
实例化A对象需要依赖B对象,实例化B对象需要依赖A对象,所以最终两个都实例化不了。
@Component
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
@Component
public class B {
private A a;
public B(A a) {
this.a = a;
}
}
Spring是无法解决构造期循环依赖的。
3,filed属性循环依赖
实例化A对象和实例化B对象之间并不相互影响,Spring是可以解决此种循环依赖的。
@Component
public class A {
@Autowired
private B b;
}
@Component
public class B {
@Autowired
private A a;
}
4,Spring是怎么解决循环依赖的?
三级缓存:
// 一级缓存,保存完整对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存,保存实例化并未初始化的对象
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存,保存ObjectFactory表达式,用于解决Aop
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);