Spring源码浅析の循环依赖
AbstractBeanFactory#doGetBean
:尝试获取bean
如果bean是单例的:
if (mbd.isSingleton()) {
//尝试获取bean <一>
sharedInstance = getSingleton(beanName, () -> {
try {
//获取不到就创建
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
//然后再次获取
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
...
}
<一>
DefaultSingletonBeanRegistry#getSingleton
方法
先从单例池中获取:Object singletonObject = this.singletonObjects.get(beanName);
如果获取不到就去创建一个:singletonObject = singletonFactory.getObject();
实际调用的是AbstractBeanFactory#createBean <二>
然后放入单例池 addSingleton(beanName, singletonObject);
<二>
重点是 Object beanInstance = doCreateBean(beanName, mbdToUse, args);
AbstractAutowireCapableBeanFactory#doCreateBean
的逻辑:
- 实例化对象:AbstractAutowireCapableBeanFactory#
createBeanInstance
- 解决循环依赖:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));<三>
}
<三>
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
锁单例池,防止并发
synchronized (this.singletonObjects) {
单例池中找不到当前bean
if (!this.singletonObjects.containsKey(beanName)) {
在三级缓存中放入 k:当前bean名称 value 工厂
this.singletonFactories.put(beanName, singletonFactory);
二级缓存删除当前bean的名称
this.earlySingletonObjects.remove(beanName);
保存当前已经注册单例bean的名称
this.registeredSingletons.add(beanName);
}
}
}
- 属性赋值:AbstractAutowireCapableBeanFactory#
populateBean
- 初始化:AbstractAutowireCapableBeanFactory#
initializeBean
循环依赖:A和B两个实例,A的属性是B,B的属性是A
前提条件,A和B都是单例的。假设目前要初始化A:
1、AbstractBeanFactory#doGetBean
尝试获取A
2、获取不到,AbstractBeanFactory#createBean
创建A
2.1、实例化A
2.2、解决循环依赖:在三级缓存中放入k:a,V:A的工厂
2.3、设置属性,发现需要B
2.3.1、AbstractBeanFactory#doGetBean
尝试获取B
2.3.2、获取不到,AbstractBeanFactory#createBean
创建B
2.3.2.1、实例化B
2.3.2.2、解决循环依赖:在三级缓存中放入k:b,V:B的工厂
2.3.2.3、设置属性,发现需要A,再次调用AbstractBeanFactory#doGetBean
(在AbstractAutowireCapableBeanFactory#autowireByName
的getBean
) ,走Object sharedInstance = getSingleton(beanName);<四>
2.3.2.4、初始化B,DefaultSingletonBeanRegistry#addSingleton
中将B放入一级缓存,删除二级缓存
2.4、初始化A,DefaultSingletonBeanRegistry#addSingleton
中将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);
//根据bean的名称找到bean工厂
if (singletonFactory != null) {
//创建bean
singletonObject = singletonFactory.getObject();
//放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//从三级缓存中清除
this.singletonFactories.remove(beanName);
}
}
}
}
//返回bean的实例
return singletonObject;
}
小结
doGetBean
中有两个getSingleton
方法,第一个用于解决依赖循环问题,第二个只有一级缓存
中没有对应bean的时候,才会调用createBean
,实例化,向三级缓存
中提前曝光。属性设置,初始化都是在createBean
中的