何为循环依赖?
循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如图:
循环依赖如何解决?
① 主bean通过属性或者setter方法注入所依赖的bean,不是通过构造函数注入
② 通过三级缓存实现:singletonObjects,earlySingletonObjects和singletonFactories;
通过spring-beans包下的DefaultSingletonBeanRegistry类完成
//一级缓存singletonObject,一级缓存需要用JUC
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//三级缓存singletonFactory,在synchronized中执行无需考虑线程安全
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//二级缓存earlySingletonObjects,在synchronized中执行无需考虑线程安全
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
主要是类中的getSingleton方法完成,我们看下getSingleton方法源码实现:
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//通过beanName获取一级缓存对象
Object singletonObject = this.singletonObjects.get(beanName);
//当前对象不在这个单例中 && bean正在创建中
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
//获取二级缓存对象earlySingletonObjects
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存对象不在此单例中而且允许创建
if (singletonObject == null && allowEarlyReference) {
//三级缓存对象创建
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//三级缓存对象创建成功并放入二级缓存中
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
//移除一级缓存
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
实现过程是这样的,创建主bean时通过getSingleton将主bean放入上述的isSingletonCurrentlyInCreation列表中,从而使上面的方法实现二三级缓存。
DefaultSingletonBeanRegistry类中还有一个public的getSingleton方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory){
synchronized(this.singletonObjects) {
//获取一级缓存
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//...部分判断省略
//将当前beanName放入singletonsCurrentlyInCreation中,以便解决循环依赖问题
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//直接获取三级缓存中的对象
//getObject方法会调用AbstractAutowireCapableBeanFactory的createBean方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch ...省略部分代码
}
return singletonObject;
}
}
看下createBean方法,本质是调用AbstractAutowireCapableBeanFactory的doCreateBean方法:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 省略其他代码
// 1\. 调用构造函数创建该bean对象,若不存在构造函数注入,顺利通过
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 2\. 在singletonFactories缓存中,放入该bean对象,以便解决循环依赖问题
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3\. populateBean方法:bean对象的属性赋值
populateBean(beanName, mbd, instanceWrapper);
// 省略其他代码
}
注意<u style="box-sizing: border-box;">addSingleton</u>方法,最后,都会将单例bean对象放入一级缓存singletonObjects中,并移除存放提前曝光对象的二级缓存earlySingletonObjects和该bean对象的创建工厂缓存earlySingletonObjects,解决循坏依赖的问题
网友评论