@Configuration @RequiredArgsConstructor public class Adam { private final Eve eve; } 复制代码
@RequiredArgsConstructor @Configuration public class Eve { private final Adam adam; } 复制代码
AbstractAutowireCapableBeanFactory->createBeanInstance(): Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } 复制代码
在选择构造器注入的时候,会遍历字段,根据beanClass反推beanName,然后实例化。 一路debug,最终找到了抛出异常的调用栈:
DefaultSingletonBeanRegistry->getSingleton(): beforeSingletonCreation(beanName); DefaultSingletonBeanRegistry->beforeSingletonCreation(): if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } 复制代码
与之对应的是afterSingletonCreation方法
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } 复制代码
singletonsCurrentlyInCreation是一个Set集合,表示当前正在创建的bean名称,创建完成后,会移除。
原来,当同一个bean未完成实例化,又再一次实例化时,singletonsCurrentlyInCreation.add(beanName)返回false,进而抛出了异常,导致程序报错
@Component public class Adam { @Autowired private eve; } 复制代码
@Component public class Eve { @Autowired private Adam adam; } 复制代码
这样写发现并没有报错,一路debug,发现是这段代码起的作用:
AbstractBeanFactory->doGetBean(): Object sharedInstance = getSingleton(beanName); AbstractBeanFactory->getSingleton(): return getSingleton(beanName, true); AbstractBeanFactory->getSingleton(): // 此时singletonObjects未完成,所以肯定是null Object singletonObject = this.singletonObjects.get(beanName); // 根据前面的分析,singletonsCurrentlyInCreation肯定包含beanName if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } 复制代码
此时发现, earlySingletonObjects.get(beanName)
为空, singletonFactories.get(beanName)
获取到了值,继而获取到了singletonObject(这里看出 earlySingletonObjects创建,对应的singletonFactory会移除
)。重新debug,发现是这里给singletonFactories赋了值:
AbstractAutowireCapableBeanFactory->doCreateBean(): if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } DefaultSingletonBeanRegistry->addSingletonFactory(): synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } 复制代码
这段代码是在实例化完成之后进行的,也就是说,当构造器注入的时候,并没有添加到singletonFactories,所以 getSingleton(beanName)
返回空,进行了第二次的实例化,从而导致报错(这里看出 singletonFactories创建,对应的earlySingletonObjects会移除
)。继续debug,最终singletonFactories和earlySingletonObjects都被清除了:
DefaultSingletonBeanRegistry->getSingleton(): addSingleton(beanName, singletonObject); DefaultSingletonBeanRegistry->addSingleton(): synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } 复制代码
当singletonObjects创建的时候,earlySingletonObjects和singletonFactories的使命就完成了~
对于字段注入,IoC容器使用了singletonFactories和earlySingletonObjects来预防循环依赖。