spring解决循环依赖主要通过三级缓存去完成。
/** Cache of singleton objects: bean name --> bean instance */
private final Map singletonObjects = new ConcurrentHashMap(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map> singletonFactories = new HashMap>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map earlySingletonObjects = new HashMap(16);
在doGetBean中,它首先会通过getSingleton方法去尝试获取bean。
Object sharedInstance = getSingleton(beanName);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
/** 首先从singletonObjects获取bean实例 */
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
/**
* 如果singletonObjects还没有此bean,有两种情况
* 1.这个bean正在创建状态,先从earlySingletonObjects获取
* 2.这个bean还没开始创建
*/
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
/**
* 如果earlySingletonObjects还没有此bean,有两种情况
* 1.说明还未被其他bean注入,正在创建状态,先从singletonFactories获取
* 2.该bean还没开始创建
*/
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
//将此bean放到提前缓存到earlySingletonObjects中
this.earlySingletonObjects.put(beanName, singletonObject);
//从singletonObject删除bean
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
这个方法做了这么一件事,逐步从三级缓存中获取bean:
相应的在doCreateBean中有这么一串代码:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//BeanWrapper是用来持有创建出来的Bean对象的
BeanWrapper instanceWrapper = null;
//如果是Singleton先把缓存中同名的清除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//这是创建Bean的地方由createBeanInstance来完成
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory
核心在这里:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory
这串代码会在创建bean的时候将自身注册进singletonFactories中。所以可以想象当两个bean互相依赖时,A会将自身注册进singletonFactories中,当它创建B时它可以直接从singletonFactories中获取A的引用所以B能成功创建,当B成功创建后那A也可以从singletonObjects中获取B的引用,最后A也成功创建。
Spring通过三级缓存解决了循环依赖的问题,它会在创建bean的时候将自身注册进一个singletonFactory中,然后创建它的依赖bean时会从这个缓存中获取它的引用使那个依赖bean先进行创造,最后完成自身的依赖。
举个列子: