什么是循环依赖?
所谓的循环依赖就是A依赖B,B依赖A,或者是A依赖B,B依赖C,C依赖A
代码实例:
getter/setter
public class InstanceA {
private InstanceB instanceB;
}
public class InstanceB {
private InstanceA instanceA;
}
<bean id="instanceA" class="com.tuling.circulardependencies.InstanceA">
<property name="instanceB" ref="intanceB"></property>
</bean>
<bean id="intanceB" class="com.tuling.circulardependencies.InstanceB">
<property name="instanceA" ref="instanceA"></property>
</bean>
可能存在的问题:
IOC容器在创建Bean的时候,按照顺序,先去实例化instanceA。然后突然发现我的instanceA是依赖我
的instanceB的。
那么IOC容器接着去实例化intanceB,那么在intanceB的时候发现依赖instanceA。若容器不处理的,
那么IOC 将无限的执行
上述流程。直到内存异常程序奔溃.
解决方案:
当然,Spring 是不会让这种情况发生的。在容器发现 beanB 依赖于 beanA 时,容器会获取 beanA
对象的一个早期的引用(early reference),并把这个早期引用注入到 beanB 中,让 beanB 先完成实例
化。beanB 完成实例化,beanA 就可以获取到 beanB 的引用,beanA 随之完成实例化。
看下如下代码调用链
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否有初始化好的bean
Object singletonObject = this.singletonObjects.get(beanName);
判断 beanName 对应的 bean 是否正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//加锁,防止多线程并发创建
synchronized (this.singletonObjects) {
//从 earlySingletonObjects 中获取提前曝光的 bean
singletonObject = this.earlySingletonObjects.get(beanName);
//也没有
if (singletonObject == null && allowEarlyReference) {
获取相应的 bean 工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) { //有
/ // 提前曝光 bean 实例(raw bean),用于解决循环依赖
singletonObject = singletonFactory.getObject();
// 将 singletonObject 放入缓存中,并将 singletonFactory 从缓存中移除
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
用于存放 beanName和 初始化好的bean对象(属性已经初始化好的)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
存放 bean 工厂对象,用于解决循环依赖
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
用于存放beanName 和一个原始bean 早期bean(属性未初始化)
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);