CASE:“A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”。
剖析:
1.A进行create流程,发现自己依赖B,此时B更没有走create流程。
doCreateBean()中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
isSingletonCurrentlyInCreation(beanName)的具体实现是:
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
那么它的调用机会又是什么时候呢?
DefaultSingletonBeanRegistry.getSingleton();
AbstractBeanFactory.doGetBean()中也就是AbstractBeanFactory.getBean()调用了下面这个办法.
在这里还有一个调用链路就是:
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)->
beanFactory.preInstantiateSingletons()->AbstractBeanFactory.getBean().
在这里,我目前先探讨这两个次要的调用链路,其余的当前再说。
咱们接着剖析,如果判断出循环援用,则执行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) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
见到了相熟的singletonFactories,是不是很兴奋呢;此时,A将本人放入到singletonFactories中。
2.发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以B走create流程。
3.B初始化时时候发现自己依赖A,尝试get(A),从singletonObjects(一级缓存)中取,发现没有(此时A还没有初始化实现),earlySingletonObjects(二级缓存)中也没有,最初从singletonFactories(三级缓存)中取,因为在1中A曾经寄存在singletonFactories外面了,所以B能够拿到A(尽管是个半成品)。
4.此时,B能够顺利完成初始化,并将本人放在singletonObjects中。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
if (newSingleton) {
//增加到singletonObjects中
addSingleton(beanName, singletonObject);
}
}
上面看,具体实现:
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
5.此时返回A中,A此时能拿到B,最终A也实现了初始化,进去了一级缓存singletonObjects中。
发表回复