最后,再来看看第三行代码,核心就是这句 method.equals(ClassUtils.getMostSpecificMethod(method, clazz)。这句代码的主要目的就是为了处理下面这种情况
@Component public class D extends C { @Autowired @Override public void setDmzService(DmzService dmzService) { dmzService.init(); this.dmzService = dmzService; } } // C不是Spring中的组件 public class C { DmzService dmzService; @Autowired public void setDmzService(DmzService dmzService) { this.dmzService = dmzService; } }这种情况下,在处理D中的@Autowired注解时,虽然我们要处理父类中的@Autowired注解,但是因为子类中的方法已经复写了父类中的方法,所以此时应该要跳过父类中的这个被复写的方法,这就是第三行代码的作用。
小结到这里我们主要分析了applyMergedBeanDefinitionPostProcessors这段代码的作用,它的执行时机是在创建对象之后,属性注入之前。按照官方的定义来说,到这里我们仍然可以使用这个方法来修改bd的定义,那么相对于通过BeanFactoryPostProcessor的方式修改bd,applyMergedBeanDefinitionPostProcessors这个方法影响的范围更小,BeanFactoryPostProcessor影响的是整个Bean的生命周期,而applyMergedBeanDefinitionPostProcessors只会影响属性注入之后的生命周期。
其次,我们分析了Spring中内置的MergedBeanDefinitionPostProcessor,选取了其中两个特殊的后置处理器进行分析,其中ApplicationListenerDetector主要处理内嵌的事件监听器,而AutowiredAnnotationBeanPostProcessor主要用于处理@Autowired注解,实际上我们会发现,到这里还只是完成了@Autowired注解的解析,还没有真正开始进行注入,真正注入的逻辑在后面我们要分析的populateBean方法中,在这个方法中会使用解析好的注入元信息完成真正的属性注入,那么接下来我们就开始分析populateBean这个方法的源码。
populateBean循环依赖的代码我们暂且跳过,后续出一篇专门文章解读循环依赖,我们直接看看populateBean到底做了什么。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 处理空实例 if (bw == null) { // 如果创建的对象为空,但是在XML中又配置了需要注入的属性的话,那么直接报错 if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // 空对象,不进行属性注入 return; } } // 满足两个条件,不是合成类 && 存在InstantiationAwareBeanPostProcessor // 其中InstantiationAwareBeanPostProcessor主要作用就是作为Bean的实例化前后的钩子 // 外加完成属性注入,对于三个方法就是 // postProcessBeforeInstantiation 创建对象前调用 // postProcessAfterInstantiation 对象创建完成,@AutoWired注解解析后调用 // postProcessPropertyValues(已过期,被postProcessProperties替代) 进行属性注入 // 下面这段代码的主要作用就是我们可以提供一个InstantiationAwareBeanPostProcessor // 提供的这个后置处理如果实现了postProcessAfterInstantiation方法并且返回false // 那么可以跳过Spring默认的属性注入,但是这也意味着我们要自己去实现属性注入的逻辑 // 所以一般情况下,我们也不会这么去扩展 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // 这里其实就是判断XML是否提供了属性相关配置 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 确认注入模型 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 主要处理byName跟byType两种注入模型,byConstructor这种注入模型在创建对象的时候已经处理过了 // 这里都是对自动注入进行处理,byName跟byType两种注入模型均是依赖setter方法 // byName,根据setter方法的名字来查找对应的依赖,例如setA,那么就是去容器中查找名字为a的Bean // byType,根据setter方法的参数类型来查找对应的依赖,例如setXx(A a),就是去容器中查询类型为A的bean if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } // pvs是XML定义的属性 // 自动注入后,bean实际用到的属性就应该要替换成自动注入后的属性 pvs = newPvs; } // 检查是否有InstantiationAwareBeanPostProcessor // 前面说过了,这个后置处理器就是来完成属性注入的 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否需要依赖检查,默认是不会进行依赖检查的 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); // 下面这段代码有点麻烦了,因为涉及到版本问题 // 其核心代码就是调用了postProcessProperties完成了属性注入 PropertyDescriptor[] filteredPds = null; // 存在InstantiationAwareBeanPostProcessor,我们需要调用这类后置处理器的方法进行注入 if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 这句就是核心 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { // 得到需要进行依赖检查的属性的集合 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 这个方法已经过时了,放到这里就是为了兼容老版本 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } // 需要进行依赖检查 if (needsDepCheck) { if (filteredPds == null) { // 得到需要进行依赖检查的属性的集合 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 对需要进行依赖检查的属性进行依赖检查 checkDependencies(beanName, mbd, filteredPds, pvs); } // 将XML中的配置属性应用到Bean上 if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }上面这段代码主要可以拆分为三个部分
处理自动注入
处理属性注入(主要指处理@Autowired注解),最重要
处理依赖检查
处理自动注入 autowireByName