在上一篇中我们分析完了**createBean()**,并详解讲解了三中创建单实例bean对象的方法,在bean实例创建出来之后,就是对bean的属性赋值和初始化操作,本篇我们继续往下分析。

1.populateBean()

  1. protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2. /*这里是判断假如beanWrapper是空,但是mbd中的属性还有值,那就说明需要抛出异常,因为没法给一个null赋值。*/
  3. if (bw == null) {
  4. if (mbd.hasPropertyValues()) {
  5. throw new BeanCreationException(
  6. mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
  7. } else {
  8. // Skip property population phase for null instance.
  9. return;
  10. }
  11. }
  12. /*在设置属性之前,给任何实例化的bean后处理器修改bean状态的机会。例如,这可以用来支持各种类型的属性注入。*/
  13. /*
  14. * mbd.isSynthetic()默认是false,取反成立。
  15. * 判断有没有instantiationAwareBeanPostProcessors,条件成立说明有。
  16. */
  17. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  18. /*这里又是后置处理器的一个调用点:实例化之后的调用,调用的是后置处理器的afterInstantiation方法。*/
  19. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  20. /*返回值将决定当前实例需要在进行依赖注入处理,默认返回true*/
  21. if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  22. return;
  23. }
  24. }
  25. }
  26. /*下面是处理依赖注入的逻辑*/
  27. /*三元运算符获取属性,有就把属性赋值给pvs ,没有就给一个null*/
  28. PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
  29. int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  30. /*这里判断依赖注入是按照名字注入还是按照类型注入,根据不同的选择走不同的处理逻辑。*/
  31. if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  32. /*吧属性进行一个包装*/
  33. MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  34. // Add property values based on autowire by name if applicable.
  35. /*按照名字注入,根据字段名称查找依赖bean完成注入*/
  36. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
  37. autowireByName(beanName, mbd, bw, newPvs);
  38. }
  39. // Add property values based on autowire by type if applicable.
  40. /*按照类型注入*/
  41. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  42. autowireByType(beanName, mbd, bw, newPvs);
  43. }
  44. /*相当于处理了依赖数据后的pvs*/
  45. pvs = newPvs;
  46. }
  47. /*表示当前是否拥有instantiationAwareBeanPostProcessors需要执行*/
  48. boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  49. /*是否需要进行依赖检察,不重要*/
  50. boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
  51. PropertyDescriptor[] filteredPds = null;
  52. if (hasInstAwareBpps) {
  53. if (pvs == null) {
  54. pvs = mbd.getPropertyValues();
  55. }
  56. /*后置处理器的调用点*/
  57. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  58. /*典型应用:@Autowired 注解的注入*/
  59. PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  60. if (pvsToUse == null) {
  61. if (filteredPds == null) {
  62. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  63. }
  64. pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  65. if (pvsToUse == null) {
  66. return;
  67. }
  68. }
  69. pvs = pvsToUse;
  70. }
  71. }
  72. if (needsDepCheck) {
  73. if (filteredPds == null) {
  74. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  75. }
  76. checkDependencies(beanName, mbd, filteredPds, pvs);
  77. }
  78. if (pvs != null) {
  79. /*将完成依赖注入(合并后的pvs)的信息应用到实例上去*/
  80. /**
  81. * 1.对man进行属性赋值的过程
  82. * 2.对women进行属性赋值
  83. */
  84. applyPropertyValues(beanName, mbd, bw, pvs);
  85. }
  86. }

  1. 上来一套组合拳,先判断假如bean包装对象是空的,但是mbd中的属性还有值,那就说明需要抛出异常,因为没法给一个null赋值。
  2. 接下来就是在属性赋值之前,给任何实例化的bean后置处理器修改bean状态的机会。例如,这可以用来支持各种类型的属性注入。**InstantiationAwareBeanPostProcessors**

    这里又是一个后置处理器的调用点,实例化之后的调用,调用的是后置处理器的**afterInstantiation**方法。这个处理器的返回值将决定当前bean实例是否要进行属性注入,返回false则表示直接返回,默认返回true。�

  3. 判断依赖注入按照名字注入还是按照类型注入,根据不同的选择走不同的处理逻辑。注意这里的处理并不是直接注入到bean中,而是解析到pvs中。

    什么时候走这里? 必须显式的指定了配置了依赖,才会走这里。

  • 如果是按照名字注入,就执行**autowireByName()**
  • 如果是按照类型注入,就执行**autowireByType()**
  1. 判断当前是否还有**InstantiationAwareBeanPostProcessors**需要执行。
  2. 判断当前是否需要进行依赖检查、
  3. 如果还有**InstantiationAwareBeanPostProcessors**需要执行,循环执行后置处理器的方法
  4. 如果需要依赖检查,就走依赖检查的逻辑
  5. 如果合并后的依赖信息(pvs)不为空,就执行**applyPropertyValues()**进行属性赋值。

接下来分析两种属性注入的方式,按照名字注入&按照类型注入。

2.autowireByName()

    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        /*bean实例中有该字段,且有该字段的setter方法,但是在bd中没有property属性。*/
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        /*便利查找出来的集合,完成依赖注入。*/
        for (String propertyName : propertyNames) {
            /*条件成立说明beanFactory存在当前属性的bean实例,可以注入,说明找到对应的依赖信息数据了*/
            if (containsBean(propertyName)) {
                /*拿到属性所对应的bean实例*/
                Object bean = getBean(propertyName);
                /*在属性里面追加一个property*/
                pvs.add(propertyName, bean);
                /*管理依赖信息*/
                registerDependentBean(propertyName, beanName);
                if (logger.isTraceEnabled()) {
                    logger.trace("Added autowiring by name from bean name '" + beanName +
                            "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
                }
            } else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                            "' by name: no matching bean found");
                }
            }
        }
    }

总结:autowireByName主要完成以下逻辑:

  1. 获取需要填充对象得非简单类型得属性名;
  2. 遍历第一步获取得属性名,调用getBean方法从容器中获取此属性名对应的object;
  3. 然后,如果能找到,则把此属性名和object对象保存到pvs的propertyValueList里面。

    3.autowireByType()

     protected void autowireByType(
             String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
         /*获取类型转换器*/
         TypeConverter converter = getCustomTypeConverter();
         if (converter == null) {
             converter = bw;
         }
    
         Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
         /*拿到属性信息,循环遍历*/
         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
         for (String propertyName : propertyNames) {
             try {
                 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
                 // Don't try autowiring by type for type Object: never makes sense,
                 // even if it technically is a unsatisfied, non-simple property.
                 /*如果不是Object类型*/
                 if (Object.class != pd.getPropertyType()) {
                     /*拿到setter方法*/
                     MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                     // Do not allow eager init for type matching in case of a prioritized post-processor.
                     boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
                     /*包装成一个依赖描述信息对象*/
                     DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                     /*解析器根据依赖描述信息查找对象,或者 容器没有该对象实例的话,但是有该类型的bd的话,也会调用getBeanByType生成对象。*/
                     Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                     /*查询出来的依赖对象加入到pvs里面*/
                     if (autowiredArgument != null) {
                         pvs.add(propertyName, autowiredArgument);
                     }
                     /*将查询到的依赖对象注册*/
                     for (String autowiredBeanName : autowiredBeanNames) {
                         registerDependentBean(autowiredBeanName, beanName);
                         if (logger.isTraceEnabled()) {
                             logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
                                     propertyName + "' to bean named '" + autowiredBeanName + "'");
                         }
                     }
                     autowiredBeanNames.clear();
                 }
             }
             catch (BeansException ex) {
                 throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
             }
         }
     }
    
  4. 获取当前对象的非简单类型的属性名数组propertyNames;

  5. 遍历属性名数组propertyNames,获取当前属性名多对应的类型filedType;
  6. 通过filedType找到匹配的候选Bean对象;
  7. 把属性名以及bean对象添加到pvs的propertyValueList里面。

可以看到,无论是按照名字注入还是按照类型的注入方式,其实里面都会调用同一个公共的方法。**unsatisfiedNonSimpleProperties()**,接下来分析这个方法是做什么的。

    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {

        Set<String> result = new TreeSet<>();
        /*拿到配置的properties集合*/
        PropertyValues pvs = mbd.getPropertyValues();
        /*拿到bean的所有字段信息,然后便利所有的字段信息*/
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
        /*
         * 条件1成立说明 当前字段有setter方法
         * 条件2成立说明 当前字段类型是否在忽略自动注入列表中,条件成立,说明不在。
         * 条件3成立说明 当前字段不在xml或者其他方式的配置中配置过。
         * 条件4成立说明 当前字段类型是不是简单的八种基本数据类型。基本数据类型不允许自动注入。当前字段不是基本数据类型。
         * */
        for (PropertyDescriptor pd : pds) {
            if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                    !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                result.add(pd.getName());
            }
        }
        return StringUtils.toStringArray(result);
    }

过滤出mbd中符合依赖注入条件的属性。

4.applyPropertyValues()

大部分情况下,我们走属性注入的逻辑,其实都是对解析出来的依赖bean进行注入。我们来梳理一下大致的流程,看一下核心的逻辑即可。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    // 为空直接返回
    if (pvs == null || pvs.isEmpty()) {
        return;
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (System.getSecurityManager() != null) {
        if (bw instanceof BeanWrapperImpl) {
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }
    }

    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        if (mpvs.isConverted()) {
            // 如果已被设置转换完成,直接完成配置
            try {
                bw.setPropertyValues(mpvs);
                return;
            }
            catch (BeansException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
            }
        }
        original = mpvs.getPropertyValueList();
    }
    else {
        original = Arrays.asList(pvs.getPropertyValues());
    }

    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    // 创建BeanDefinitionValueResolver解析器,用来解析未被解析的PropertyValue。
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    // 开始遍历检查original中的属性,对未被解析的先解析/已解析的直接加入deepCopy中,最后再填充到具体的Bean实例中
    List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    boolean resolveNecessary = false;
    for (PropertyValue pv : original) {
        // 如果属性已经转化,直接添加
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            // 核心逻辑,解析获取实际的值
            // 对于RuntimeReference,会解析拿到具体的beanName,最终通过getBean(beanName)拿到具体的对象
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            // 判断是否可以转换
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                // 尝试进行转换
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // 避免需要重复转换,设定已转换
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }

    // 完成设置
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

主要是关心下,解析出来的依赖,如果注入到当前正在执行属性赋值的bean对象。

**valueResolver.resolveValueIfNecessary()** 利用值解析器解析当前bean实例所依赖的bean实例。

**resolveReference()**通过这个方法去拿到当前属性赋值的bean需要注入的bean。

**this.beanFactory.getBean()** 最终这里又递归回到了getBean()去获取所需要的bean对象。

**registerDependentBean()**在获取到bean对象之后,会将获取到的bean对象注册到当前bean所依赖的bean集合。

至此,单实例bean的属性赋值大体流程我们就分析完了,下一篇我们将去分析单实例bean的初始化逻辑。