Bean的屬性裝配1: InstantiationAwareBeanPostProcessor

接上文,Bean的屬性裝配前2:SmartInstantiationAwareBeanPostProcessor

回到doCreateBean方法,把單例對象緩存到第三級緩存之后,開始對這個Bean進(jìn)行屬性填充,來到populateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, 
                final @Nullable Object[] args) throws BeanCreationException {
    // ...
    // Initialize the bean instance.
    // 開始初始化Bean
    Object exposedObject = bean;
    try {
        // 此處開始為一個Bean的屬性賦值
        populateBean(beanName, mbd, instanceWrapper);
        // Bean的初始化過程,可見在屬性賦值之后,后面會討論這個過程
        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);
        }
    }
    // ...
}

/**
 *  為Bean的屬性賦值的核心方法
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, 
            @Nullable BeanWrapper bw) {

    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, 
                "Cannot apply property values to null instance");
        } else {
            // Skip property population phase for null instance.
            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.
    // 給InstantiationAwareBeanPostProcessors一次機(jī)會在屬性注入前修改Bean的狀態(tài)
    // 具體通過調(diào)用postProcessAfterInstantiation方法,
    // 如果調(diào)用返回false,表示不必繼續(xù)進(jìn)行依賴注入,直接返回
    boolean continueWithPropertyPopulation = true;

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp 
                        = (InstantiationAwareBeanPostProcessor) bp;
                // 從這里可以得到結(jié)論,一旦對某個bean進(jìn)行屬性裝配的時候,執(zhí)行此處的后置回調(diào)方法
                // 一旦某個回調(diào)返回false,那么continueWithPropertyPopulation被賦值為false
                // 后續(xù)Spring就不會為這個bean進(jìn)行屬性填充
                if (!ibp.postProcessAfterInstantiation(
                                        bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    // 如果InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation返回false
    // 則不進(jìn)行后續(xù)的屬性填充操作,包括自動裝配和@Autowired屬性注入
    if (!continueWithPropertyPopulation) {
        return;
    }

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
    // 根據(jù)Bean配置的自動裝配模式完成注入,默認(rèn)是0,即不走以下邏輯
    // 如果設(shè)置了相關(guān)的依賴裝配方式,會遍歷Bean中的屬性
    // 根據(jù)類型或名稱來完成相應(yīng)注入,無需額外配置
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME 
            || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        // 根據(jù)名稱自動裝配
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        // 根據(jù)類型自動裝配
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
    }

    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() 
            != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

    if (hasInstAwareBpps || needsDepCheck) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        PropertyDescriptor[] filteredPds 
            = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp 
                            = (InstantiationAwareBeanPostProcessor) bp;
                    pvs = ibp.postProcessPropertyValues(
                                pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            // 檢查是否滿足相關(guān)依賴關(guān)系,對應(yīng)的depends-on屬性,
            // 需要確保所有依賴的Bean先完成初始化
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }

    if (pvs != null) {
        // 將pvs上所有的屬性填充到BeanWrapper對應(yīng)的Bean實例中
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

在這里,我們又看到了熟悉的InstantiationAwareBeanPostProcessor后置處理器,在Bean的實例化過程中,Spring借助它的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation在一個Bean實例化之前回調(diào)判斷是否需要為Bean生成代理對象(Bean實例化1:InstantiationAwareBeanPostProcessor),此處Spring則是利用它的InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation回調(diào)處理,簡單的來看下這個借口的定義,它繼承了BeanPostProcessor

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 
            throws BeansException {
        return null;
    }

    /**
     * Perform operations after the bean has been instantiated, via a constructor or factory method,
     * but before Spring property population (from explicit properties or autowiring) occurs.
     * <p>This is the ideal callback for performing custom field injection on the given bean
     * instance, right before Spring's autowiring kicks in.
     * <p>The default implementation returns {@code true}.
     *
     * 在一個bean通過構(gòu)造器或者工廠方法實例化之后,在Spring為這個Bean裝配屬性之前調(diào)用
     * 這是在Spring自動注入屬性之前,為指定bean進(jìn)行自定義屬性注入的最理想回調(diào)時機(jī)
     * 結(jié)合populateBean屬性裝配方法,可以看到,當(dāng)這個方法返回false的時候,
     * 其實就是告訴Spring這個bean不需要進(jìn)行屬性裝配
     */
    default boolean postProcessAfterInstantiation(Object bean, String beanName) 
            throws BeansException {
        return true;
     }

    @Nullable
    default PropertyValues postProcessPropertyValues(PropertyValues pvs, 
            PropertyDescriptor[] pds, Object bean, String beanName) 
            throws BeansException {

        return pvs;
    }
}

總結(jié):
Spring在為bean進(jìn)行屬性填充的時候,提供了一個擴(kuò)展點InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,利用此擴(kuò)展點,可以決定某個bean是否交由Spring進(jìn)行屬性填充

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容