这一讨论的前提是要对Spring的doCreateBean方法有所了解,故将其源码放在这里,以供参考:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. // bean实例包装类 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 从未完成创建的包装Bean缓存中清理并获取相关中的包装Bean实例,毕竟是单例的,只能存一份 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建bean的时候,这里创建bean的实例有三种方法 // 1.工厂方法创建 // 2.构造方法的方式注入 // 3.无参构造方法注入 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. // 调用BeanDefinition属性合并完成后的BeanPostProcessor后置处理器 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 被@Autowired、@Value标记的属性在这里获取 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.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
对应的文章《SpringloC容器的依赖注入源码解析(7)—— doCreateBean之剩余逻辑(解决循环依赖的源头)》
现在有A依赖B,B也依赖A,假设A先创建,就会来到doCreateBean方法里,会经过各种包装,在被
instanceWrapper = createBeanInstance(beanName, mbd, args);
处理了之后生成一个没有任何属性的A的实例。
之后在调用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
之前将A实例放入到ObjectFactory里面,然后调用addSingletonFactory将ObjectFactory添加到三级缓存里,此时只有三级缓存保存了A对应的ObjectFactory实例。
随后就会调用
populateBean(beanName, mbd, instanceWrapper);
给属性赋值,由于A依赖于B,在populate里会尝试获取实例B,由于B还没有被创建过,所以又递归的调用doCreateBean方法。
在doCreateBean方法里调用
instanceWrapper = createBeanInstance(beanName, mbd, args);
创建出实例B,将其对应的实例工厂放入到三级缓存中,此时三级缓存中就保存了A和B的实例,随后在B里又会执行
populateBean(beanName, mbd, instanceWrapper);
由于B依赖A,所以在populate里尝试获取A的实例,此时调用的是AbstractBeanFactory的doGetBean方法,在里面调用:
Object sharedInstance = getSingleton(beanName);
从三级缓存里获取A实例对应的ObjectFactory实例
这里getObject()调用的就是getEarlyBeanReference方法
获取到A实例之后就会将A实例放入二级缓存里,同时清空三级缓存里的A
此时就回到创建B的doCreateBean的
populateBean(beanName, mbd, instanceWrapper);
A被注入到B里面了,即当B执行完populateBean之后就已经获取到了A,此时B就会执行完剩余逻辑获得到一个完备的B,此时方法返回到doGetBean方法里
在getSingleton方法里面会最终调用
addSingleton(beanName, singletonObject);
在方法里会将实例B添加到一级缓存里,并将B从二三级缓存里移除,表示已经彻底完成了B实例的创建,之后返回B。
B之所以会被创建是因为A调用了
populateBean(beanName, mbd, instanceWrapper);
此时又回到这个地方,A内部已经赋值上了完备的B,之后步骤同上,调用addSingleton将A放入一级缓存里,此时循环依赖的支持完成。
整个的流程图如下图所示,大家可以基于前面的介绍看一下到底有没有掌握 ~: