- 什么是循环依赖?A有B变量,B有A变量在代码看的更直观。
@Component
Class A{
@Autowired
private B b;
}
@Component
Class B{
@Autowired
private A a;
}
- spring如何解决这种循环依赖的?
singletonObjects:一级缓存,存放着对象实例化和初始化都完成的对象。
earlySingletonObjects:二级缓存,存放着从三级缓存取出的对象。
singletonFactories:三级缓存,存放着实例化完成的对象,但是还没有初始化。
答:A实例化完成之后,将A放入三级缓存当中,然后对A进行初始化给B进行赋值,但是容器中此时还没有实例化B,
所以需要去实例化B,实例化完成之后将B放入三级缓存,对B进行初始化给A赋值,此时A已经放入三级缓存中,
getSingleton()是可以拿到值。此时B已经初始化完成,将返回给A,A也完成了初始化,这样就解决了循环依赖。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从单例池中获取对象(俗称一级缓存)
Object singletonObject = this.singletonObjects.get(beanName);
//单例池中没有并且创建池有并且该对象正在处于创建的过程中(对象开始创建的时候会放入创建池中
//,初始化完成之后会从创建池中移除)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//俗称二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//俗称三级缓存
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
//从三级对象中取出放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
所以明白了为什么spring为什么解决不了构造函数的循环依赖?因为要先实例化才可以解决循环依赖。构造函数互相依赖无法实例化所以无法解决。