前置文章:
doCreateBean之处理@Autowired以及@Value标签
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; }
接上文分析到的位置,接下来执行:
// 向容器中缓存单例模式的Bean对象,以防循环引用 // 判断是否是早期引用的bean,如果是,则允许其提前暴露引用 // 这里判断的逻辑主要有三个: // 1.是否为单例 // 2.是否允许循环引用 // 3.是否是在创建中的bean boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
之后会来到
// 这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
进入到addSingletonFactory:
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); // 消除此Bean在二级缓存里的缓存信息 this.earlySingletonObjects.remove(beanName); // 这里为了记录注册单例的顺序 this.registeredSingletons.add(beanName); } } }
消除此Bean在二级缓存里的缓存信息,将其包装成singletonFactory实例往三级缓存里添加
这里有一个重点就是Spring解决循环依赖的真相就在这一段源码中:在这里beanFactory被put进了singletonFactories,此时的bean只是完成了初始化构造的bean,还没有进行set或者注解注入的bean,是bean的一个中间状态,但是已经能被人认出来了,所以Spring此时将这个对象提前曝光出来让大家认识、使用。
回到doCreateBean,进入到getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { // 如果是SmartInstantiationAwareBeanPostProcessor类型,就进行处理, // 如果没有相关处理内容,就返回默认的实例。 // 里面的AbstractAutoProxyCreator类是后续AOP的关键 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; // 对单例进行AOP包装并返回的地方! exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
注意这个方法并不是在doCreateBean的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这一行执行的,这里只是将getEarlyBeanReference注册进去,实际执行的地方是前面尝试从缓存里获取bean的地方,即AbstractBeanFactory的doCreateBean方法里。
回到doCreateBean,此时获取到了bean,并且只在三级缓存里面保存。
之后会执行
populateBean(beanName, mbd, instanceWrapper);
来将bean的属性真正注入到里面,然后再调用initializeBean进行彻底的初始化
// Initialize the bean instance. // Bean对象的初始化,依赖注入在此触发 // 这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean Object exposedObject = bean; try { // 填充bean实例的属性 populateBean(beanName, mbd, instanceWrapper); // 初始化bean,过程如下: // 1. 判断是否实现了BeanNameAware, BeanClassLoaderAware, BeanFactoryAware方法,如果有,则设置相关的属性 // 2. 调用bean初始化的前置(BeanPostProcessor)操作 // 3. 执行初始化的方法 // 如果有initializingBean,则调用afterPropertiesSet // 如果有InitMethod,则调用初始方法 // 4. 调用bean初始化的后置(BeanPostProcessor)操作 exposedObject = initializeBean(beanName, exposedObject, mbd); }
之后判断该bean是否允许提前暴露,
if (earlySingletonExposure) { // 获取指定名称的已注册的单例模式Bean对象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { // 如果经过initializeBean执行后返回的bean还是同一个(不是代理对象实例,即没有被增强) if (exposedObject == bean) { // 确保根据名称获取到的的已注册的Bean和正在实例化的Bean是同一个 exposedObject = earlySingletonReference; } ...... } }
if 里面调用了getSingleton方法,进入该方法:
@Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(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); } } } } return singletonObject; }
和之前提到的是同一个方法,由于这时bean已经被放到三级缓存里了,所以会被从三级缓存里取出
singletonObject = singletonFactory.getObject();
获取到bean实例之后会将其从三级缓存里移除
this.singletonFactories.remove(beanName);
回到doCreateBean,
Object earlySingletonReference = getSingleton(beanName, false);
执行完毕之后再判断一下
if (exposedObject == bean) { // 确保根据名称获取到的的已注册的Bean和正在实例化的Bean是同一个 exposedObject = earlySingletonReference; }
exposedObject由于之前调用了initializeBean方法,所以有可能会被赋值为全新的对象,一旦被赋值了全新的对象之后if里面是false,进入到前面的initializeBean方法里
重点关注applyBeanPostProcessorsAfterInitialization方法,进入到方法里:
重点关注实现了postProcessAfterInitialization方法的AbstractAutoProxyCreator类
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
该方法尝试从缓存里获取bean实例并返回,即如果先前加工过的话就返回bean实例,确保加工过的bean实例和先前是同一个。
回到doCreateBean,
if (exposedObject == bean) { // 确保根据名称获取到的的已注册的Bean和正在实例化的Bean是同一个 exposedObject = earlySingletonReference; }else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); // 获取依赖于当前Bean的Bean实例 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."); } }
如果不是同一个bean,则有可能经过initializeBean之后没有返回同样的bean实例,之所以会出现这个问题是因为postProcessor也是供用户使用的,用户可能在自定义逻辑里修改了bean实例,用户的行为对于系统来说是无法预测的。
不一样的话就会检查有没有别的bean依赖于这个bean,如果存在则直接报错,因为既然执行到这里其他bean实例就已经执行过了populate方法将该bean的实例设置上了,然而设置上了之后却又创建出了该bean的新实例,于是就不满足单例。
通过验证之后会注册销毁时候的回调逻辑
registerDisposableBeanIfNecessary(beanName, bean, mbd);