23--Spring创建Bean的过程(五),bean属性填充过程简析

版权声明:如有转载,请标明出处,谢谢合作! https://blog.csdn.net/lyc_liyanchao/article/details/82699409

上一小节我们简介了一下Spring中的循环依赖,并简单介绍了Spring对Setter循环依赖的解决方法,好让大家对接下来的分析有所准备,在

中我们已经分析了Spring通过无参和实参两种方式创建bean的实例,接下来我们会分析创建bean实例之后的操作:填充bean的属性,该过程大概可分为以下步骤

  • ① 前置判断,对BeanWrapper的合法性进行判断
  • ② 应用InstantiationAwareBeanPostProcessor处理器,在设置属性之前,给InstantiationAwareBeanPostProcessor一个修改bean状态的机会
  • ③ 如果InstantiationAwareBeanPostProcessor停止了对bean属性的填充,则直接返回
  • ④ 解析自动装配类型,对byName注入和byType注入做处理
  • ⑤ 判断是否有InstantiationAwareBeanPostProcessors处理器,并进行处理
  • ⑥ 依赖检查
  • ⑦ 应用属性

以上就是填充bean的属性的准备工作,而且属性填充工作的源码比较多,本来只是想一个用一个小节来写,但是源码实在太多,而且处理的各种分支情况也比较多,例如byName,byTpye,循环依赖处理,属性转换等。本小节就先来分析一下填充bean属性的过程,让大家先有所了解,其中的细节我们在接下来的章节中分析。

先来看下填充bean的属性的准备工作的源码。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // ① 前置判断
    // 如果BeanWrapper对象为null,则说明没有bean的实例
    if (bw == null) {
        // RootBeanDefinition中有属性,但是bean的实例为空,抛出异常
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // RootBeanDefinition中没有属性,直接返回
            return;
        }
    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    // ② 应用InstantiationAwareBeanPostProcessor处理器
    // 在设置属性之前,给InstantiationAwareBeanPostProcessor一个修改bean状态的机会
    boolean continueWithPropertyPopulation = true;

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 是否继续填充bean属性
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    // ③ 如果InstantiationAwareBeanPostProcessor停止了对bean属性的填充,则直接返回
    if (!continueWithPropertyPopulation) {
        return;
    }

    // 获取PropertyValues属性
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // ④ 解析自动装配类型
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||	mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        // byName注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        // byType注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
    }

    // ⑤ 判断是否有InstantiationAwareBeanPostProcessors处理器,并进行处理
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    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);
    }

    // ⑦ 应用属性
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

就对于步骤分析来讲,还是比较简单的,通过大家这几天大家对Spring源码的分析,相信大家也可以得出Spring对函数处理的一贯套路

  • 前置判断合法条件
  • 应用各种处理器
  • 将复杂的逻辑拆分成简单的的分支
  • 对缓存处理
  • 异常的处理
  • 。。。

而且大家可以发现,Spring很少在一个方法里写大量的代码,处理复杂的逻辑,是通过不断的拆分业务逻辑,逐渐分解成简单易懂的方法,这也是在开发中值得大家借鉴的地方。

Spring对bean属性的填充这段代码很枯燥,如果有什么吸引大家的地方,可能就是byName和byType注入吧,那么下面的章节,我们就来分析属性注入的细节。

猜你喜欢

转载自blog.csdn.net/lyc_liyanchao/article/details/82699409