读源码,我们可以从第一行读起
你知道Spring是怎么解析配置类的吗?
配置类为什么要添加@Configuration注解?
谈谈Spring中的对象跟Bean,你知道Spring怎么创建对象的吗?
推荐阅读:
Spring官网阅读 | 总结篇
Spring杂谈
本系列文章将会带你一行行的将Spring的源码吃透,推荐阅读的文章是阅读源码的基础!
前言在前面的文章中已经知道了Spring是如何将一个对象创建出来的,那么紧接着,Spring就需要将这个对象变成一个真正的Bean了,这个过程主要分为两步
属性注入
初始化
在这两个过程中,Bean的后置处理器会穿插执行,其中有些后置处理器是为了帮助完成属性注入或者初始化的,而有些后置处理器是Spring提供给程序员进行扩展的,当然,这二者并不冲突。整个Spring创建对象并将对象变成Bean的过程就是我们经常提到了Spring中Bean的生命周期。当然,本系列源码分析的文章不会再对生命周期的概念做过多阐述了,如果大家有这方面的需求的话可以参考我之前的文章,或者关注我的公众号:程序员DMZ
Spring官网阅读(九)Spring中Bean的生命周期(上)
Spring官网阅读(十)Spring中Bean的生命周期(下)
源码分析闲话不再多说,我们正式进入源码分析阶段,本文重点要分析的方法就是org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean,其源码如下:
doCreateBean protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 创建对象的过程在上篇文章中我们已经介绍过了,这里不再赘述 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { 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. // 按照官方的注释来说,这个地方是Spring提供的一个扩展点,对程序员而言,我们可以通过一个实现了MergedBeanDefinitionPostProcessor的后置处理器来修改bd中的属性,从而影响到后续的Bean的生命周期 // 不过官方自己实现的后置处理器并没有去修改bd,而是调用了applyMergedBeanDefinitionPostProcessors方法 // 这个方法名直译过来就是-应用合并后的bd,也就是说它这里只是对bd做了进一步的使用而没有真正的修改 synchronized (mbd.postProcessingLock) { // bd只允许被处理一次 if (!mbd.postProcessed) { try { // 应用合并后的bd applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } // 标注这个bd已经被MergedBeanDefinitionPostProcessor的后置处理器处理过 // 那么在第二次创建Bean的时候,不会再次调用applyMergedBeanDefinitionPostProcessors mbd.postProcessed = true; } } // 这里是用来出来循环依赖的,关于循环以来,在介绍完正常的Bean的创建后,单独用一篇文章说明 // 这里不做过多解释 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)); } Object exposedObject = bean; try { // 我们这篇文章重点要分析的就是populateBean方法,在这个方法中完成了属性注入 populateBean(beanName, mbd, instanceWrapper); // 初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { // 省略异常代码 } // 后续代码不在本文探讨范围内了,暂不考虑 return exposedObject; } applyMergedBeanDefinitionPostProcessors源码如下:
// 可以看到这个方法的代码还是很简单的,就是调用了MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }这个时候我们就要思考一个问题,容器中现在有哪些后置处理器是MergedBeanDefinitionPostProcessor呢?