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中。