Spring5IOC容器解析——createBean()方法分析下

前言

接著Spring5IOC容器解析--createBean()方法分析上我們繼續(xù)解析創(chuàng)建 bean 實例的剩下內(nèi)容漾峡。

正文

首先,我們回到 doCreateBean 方法中,doCreateBean()方法主要是根據(jù) beanName、mbd挽绩、args,使用對應(yīng)的策略創(chuàng)建 bean 實例驾中,并返回包裝類 BeanWrapper唉堪。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        // 1.新建Bean包裝類
        BeanWrapper instanceWrapper = null;
        //如果RootBeanDefinition是單例的,則移除未完成的FactoryBean實例的緩存
        if (mbd.isSingleton()) {
            // 2.如果是FactoryBean肩民,則需要先移除未完成的FactoryBean實例的緩存
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 3.根據(jù)beanName唠亚、mbd、args持痰,使用對應(yīng)的策略創(chuàng)建Bean實例灶搜,并返回包裝類BeanWrapper
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 4.拿到創(chuàng)建好的Bean實例
        final Object bean = instanceWrapper.getWrappedInstance();
        // 5.拿到Bean實例的類型
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // 6.應(yīng)用后置處理器MergedBeanDefinitionPostProcessor,允許修改MergedBeanDefinition工窍,
                    // Autowired注解割卖、Value注解正是通過此方法實現(xiàn)注入類型的預(yù)解析
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        // 7.判斷是否需要提早曝光實例:單例 && 允許循環(huán)依賴 && 當(dāng)前bean正在創(chuàng)建中
        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");
            }
            // 8.提前曝光beanName的ObjectFactory,用于解決循環(huán)引用
            // 8.1 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor患雏,允許返回指定bean的早期引用鹏溯,若沒有則直接返回bean
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        // 初始化bean實例。
        Object exposedObject = bean;
        try {
            // 9.對bean進(jìn)行屬性填充淹仑;其中丙挽,可能存在依賴于其他bean的屬性,則會遞歸初始化依賴的bean實例
            populateBean(beanName, mbd, instanceWrapper);
            // 10.對bean進(jìn)行初始化
            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);
            }
        }

        if (earlySingletonExposure) {
            // 11.如果允許提前曝光實例匀借,則進(jìn)行循環(huán)依賴檢查
            Object earlySingletonReference = getSingleton(beanName, false);
            // 11.1 earlySingletonReference只有在當(dāng)前解析的bean存在循環(huán)依賴的情況下才會不為空
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    // 11.2 如果exposedObject沒有在initializeBean方法中被增強颜阐,則不影響之前的循環(huán)引用
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    // 11.3 如果exposedObject在initializeBean方法中被增強 && 不允許在循環(huán)引用的情況下使用注入原始bean實例
                    // && 當(dāng)前bean有被其他bean依賴
                    // 11.4 拿到依賴當(dāng)前bean的所有bean的beanName數(shù)組
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        // 11.5 嘗試移除這些bean的實例,因為這些bean依賴的bean已經(jīng)被增強了吓肋,他們依賴的bean相當(dāng)于臟數(shù)據(jù)
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            // 11.6 移除失敗的添加到 actualDependentBeans
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        // 11.7 如果存在移除失敗的凳怨,則拋出異常,因為存在bean依賴了“臟數(shù)據(jù)”
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            // 12.注冊用于銷毀的bean蓬坡,執(zhí)行銷毀操作的有三種:自定義destroy方法猿棉、DisposableBean接口磅叛、DestructionAwareBeanPostProcessor
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
        // 13.完成創(chuàng)建并返回
        return exposedObject;
    }
}
  • earlySingletonReference 只有在當(dāng)前解析的 bean 存在循環(huán)依賴的情況下才會不為空屑咳。

因為如果不是循環(huán)依賴萨赁,只會在完全創(chuàng)建完 bean 實例才會添加到 singletonObjects 緩存。此時兆龙,我們正在創(chuàng)建 bean 的過程中杖爽,還沒有完全創(chuàng)建完,singletonObjects 緩存是肯定沒有當(dāng)前 beanName 的紫皇;而如果不存在循環(huán)引用慰安,從 doGetBean 方法開始,getSingleton 方法只會在最初 doGetBean 方法里調(diào)用一次聪铺,不存在循環(huán)引用化焕,也就用不到提前曝光的 ObjectFactory 來創(chuàng)建 bean 對象,從而 earlySingletonObjects 緩存肯定也是沒有 beanName 的 bean 實例對象的铃剔,所以必然返回空撒桨。

  • 注冊用于銷毀的 bean,執(zhí)行銷毀操作的有三種:自定義 destroy 方法键兜、DisposableBean 接口凤类、DestructionAwareBeanPostProcessor。

applyMergedBeanDefinitionPostProcessors

  • 應(yīng)用后置處理器 MergedBeanDefinitionPostProcessor普气,允許修改MergedBeanDefinition谜疤,Autowired注解、Value注解正是通過此方法實現(xiàn)注入類型的預(yù)解析现诀。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        // 1.獲取BeanFactory中已注冊的BeanPostProcessor
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                // 2.調(diào)用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                //重點關(guān)注AutowiredAnnotationBeanPostProcessor夷磕,該類會把@Autowired等標(biāo)記的
                //需要依賴注入的成員變量或者方法實例給記錄下來,方便后續(xù)populateBean使用
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }
}

addSingletonFactory

  • 提前曝光beanName的ObjectFactory仔沿,用于解決循環(huán)引用企锌。

  • 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor,允許返回指定bean的早期引用于未,若沒有則直接返回bean撕攒。

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    /** Cache of singleton objects: bean name to bean instance. */
    //一級緩存:單例對象緩存池,beanName->Bean烘浦,其中存儲的就是實例化抖坪,屬性賦值成功之后的單例對象
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /** Cache of singleton factories: bean name to ObjectFactory. */
    //三級緩存:單例工廠的緩存,beanName->ObjectFactory闷叉,添加進(jìn)去的時候?qū)嵗€未具備屬性
    // 用于保存beanName和創(chuàng)建bean的工廠之間的關(guān)系map擦俐,單例Bean在創(chuàng)建之初過早的暴露出去的Factory,
    // 為什么采用工廠方式握侧,是因為有些Bean是需要被代理的蚯瞧,總不能把代理前的暴露出去那就毫無意義了
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name to bean instance. */
    //二級緩存:早期的單例對象嘿期,beanName->Bean,其中存儲的是實例化之后埋合,屬性未賦值的單例對象
    // 執(zhí)行了工廠方法生產(chǎn)出來的Bean备徐,bean被放進(jìn)去之后,
    // 那么當(dāng)bean在創(chuàng)建過程中甚颂,就可以通過getBean方法獲取到
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    /** Set of registered singletons, containing the bean names in registration order. */
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            // 1.如果beanName不存在于singletonObjects緩存中
            if (!this.singletonObjects.containsKey(beanName)) {
                //往三級緩存里添加
                // 2.將beanName和singletonFactory注冊到singletonFactories緩存(beanName -> 該beanName的單例工廠)
                this.singletonFactories.put(beanName, singletonFactory);
                //清除此Bean在二級緩存里的緩存信息
                // 3.移除earlySingletonObjects緩存中的beanName(beanName -> beanName的早期單例對象)
                this.earlySingletonObjects.remove(beanName);
                //這里為了記錄注冊單例的順序
                // 4.將beanName注冊到registeredSingletons緩存(已經(jīng)注冊的單例集合)
                this.registeredSingletons.add(beanName);
            }
        }
    }
}

Spring5IOC容器解析--refresh()方法分析中蜜猾,通過提前曝光的 ObjectFactory 獲得 “不完整” 的 bean 實例,從而解決循環(huán)引用的問題振诬,ObjectFactory 就是通過這邊的 singletonFactories緩存來進(jìn)行曝光的蹭睡。

getEarlyBeanReference

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        // 1.如果bean不為空 && mbd不是合成 && 存在InstantiationAwareBeanPostProcessors
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                // 2.應(yīng)用所有SmartInstantiationAwareBeanPostProcessor,調(diào)用getEarlyBeanReference方法
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    // 3.允許SmartInstantiationAwareBeanPostProcessor返回指定bean的早期引用
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }
        // 4.返回要作為bean引用公開的對象赶么,如果沒有SmartInstantiationAwareBeanPostProcessor修改肩豁,則返回的是入?yún)⒌腷ean對象本身
        return exposedObject;
    }
}

populateBean

  • 對 bean 進(jìn)行屬性填充;其中辫呻,可能存在依賴于其他 bean 的屬性清钥,則會遞歸初始化依賴的 bean 實例。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

        // bw為空時的處理
        if (bw == null) {
            // 如果bw為空印屁,屬性不為空循捺,拋異常,無法將屬性值應(yīng)用于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.
                // 如果bw為空雄人,屬性也為空从橘,則跳過
                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最后一次機會在屬性注入前修改Bean的屬性值,也可以控制是否繼續(xù)填充Bean
        // 具體通過調(diào)用postProcessAfterInstantiation方法础钠,如果調(diào)用返回false,表示不必繼續(xù)進(jìn)行依賴注入恰力,直接返回
        // 主要是讓用戶可以自定義屬性注入。比如用戶實現(xiàn)一個 InstantiationAwareBeanPostProcessor 類型的后置處理器旗吁,
        // 并通過 postProcessAfterInstantiation 方法向 bean 的成員變量注入自定義的信息踩萎。
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            // 如果mbd不是合成的 && 存在InstantiationAwareBeanPostProcessor,則遍歷處理InstantiationAwareBeanPostProcessor
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 在bean實例化后很钓,屬性填充之前被調(diào)用香府,允許修改bean的屬性,如果返回false码倦,則跳過之后的屬性填充
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        return;
                    }
                }
            }
        }

        // pvs是一個MutablePropertyValues實例企孩,里面實現(xiàn)了PropertyValues接口,
        // 提供屬性的讀寫操作實現(xiàn)袁稽,同時可以通過調(diào)用構(gòu)造函數(shù)實現(xiàn)深拷貝
        //獲取BeanDefinition里面為Bean設(shè)置上的屬性值
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        // 根據(jù)Bean配置的依賴注入方式完成注入勿璃,默認(rèn)是0,即不走以下邏輯,所有的依賴注入都需要在xml文件中有顯式的配置
        // 如果設(shè)置了相關(guān)的依賴裝配方式补疑,會遍歷Bean中的屬性歧沪,根據(jù)類型或名稱來完成相應(yīng)注入,無需額外配置
        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            // 根據(jù)beanName進(jìn)行autowiring自動裝配處理
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            //根據(jù)Bean的類型進(jìn)行autowiring自動裝配處理
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }
        //BeanFactory是否注冊過InstantiationAwareBeanPostProcessors
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        //是否進(jìn)行依賴檢查莲组,默認(rèn)為false
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        PropertyDescriptor[] filteredPds = null;
        //注冊過InstantiationAwareBeanPostProcessors 或者 需要依賴檢查
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            // 7.1 應(yīng)用后置處理器InstantiationAwareBeanPostProcessor
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //在這里會對@Autowired標(biāo)記的屬性進(jìn)行依賴注入
                    //調(diào)用AutowiredAnnotationBeanPostProcessor的postProcessProperties
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        // 對解析完但未設(shè)置的屬性再進(jìn)行處理
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        // 依賴檢查诊胞,對應(yīng)depend-on屬性,3.0已經(jīng)棄用此屬性
        if (needsDepCheck) {
            // 過濾出所有需要進(jìn)行依賴檢查的屬性編輯器
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        if (pvs != null) {
            //最終將屬性注入到Bean的Wrapper實例里胁编,這里的注入主要是供
            //顯式配置了autowiredbyName或者ByType的屬性注入厢钧,
            //針對注解來講鳞尔,由于在AutowiredAnnotationBeanPostProcessor已經(jīng)完成了注入嬉橙,
            //所以此處不執(zhí)行
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }
}

應(yīng)用后置處理器 InstantiationAwareBeanPostProcessor 的方法 postProcessPropertyValues,進(jìn)行屬性填充前的再次處理×燃伲現(xiàn)在最常用的 @Autowire 屬性注入就是這邊注入依賴的 bean 實例對象市框,具體實現(xiàn)在 AutowiredAnnotationBeanPostProcessor的postProcessProperties方法完成注入。

將所有 PropertyValues 中的屬性填充到 bean 中糕韧。

autowireByName

  • 解析 autowireByName 的注入
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        //獲取要注入的非簡單類型的屬性名稱
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            // 檢測是否存在與 propertyName 相關(guān)的 bean 或 BeanDefinition枫振。
            // 若存在,則調(diào)用 BeanFactory.getBean 方法獲取 bean 實例
            if (containsBean(propertyName)) {
                // 從容器中獲取相應(yīng)的 bean 實例
                Object bean = getBean(propertyName);
                // 將解析出的 bean 存入到屬性值列表pvs中
                pvs.add(propertyName, bean);
                // 注冊依賴關(guān)系到緩存(beanName依賴propertyName)
                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");
                }
            }
        }
    }
}

unsatisfiedNonSimpleProperties

  • 獲取要注入的非簡單類型的屬性名稱
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    /*
     * 獲取非簡單類型屬性的名稱萤彩,且該屬性未被配置在配置文件中粪滤。
     * bean class="org.springframework.aop.framework.ProxyFactoryBean">
     *  <property name="target">
                    <ref parent="accountService"/>
     *  </property>
     * </bean>
     * Spring 認(rèn)為的"簡單類型"屬性有哪些,如下:
     *   1. CharSequence 接口的實現(xiàn)類雀扶,比如 String
     *   2. Enum
     *   3. Date
     *   4. URI/URL
     *   5. Number 的繼承類杖小,比如 Integer/Long
     *   6. byte/short/int... 等基本類型
     *   7. Locale
     *   8. 以上所有類型的數(shù)組形式,比如 String[]愚墓、Date[]予权、int[] 等等
     *
     * 除了要求非簡單類型的屬性外,還要求屬性未在配置文件中配置過浪册,也就是 pvs.contains(pd.getName()) = false扫腺。
     */
    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
        Set<String> result = new TreeSet<>();
        // 1.拿到mdb的屬性值
        PropertyValues pvs = mbd.getPropertyValues();
        // 2.拿到bw的PropertyDescriptors
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
        // 3.遍歷bw的PropertyDescriptors
        for (PropertyDescriptor pd : pds) {
            // 4.pd用于寫入屬性值的方法不為空 && pd不是從依賴性檢查中排除的bean屬性 && pd不包含在pvs里
            // && pd的屬性類型不是“簡單”屬性(基礎(chǔ)類型、枚舉村象、Number等)
            // 4.1 isSimpleProperty: 判斷屬性是不是“簡單”屬性
            if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                    !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                // 4.2 符合條件郊尝,則添加pd的name到result中
                result.add(pd.getName());
            }
        }
        return StringUtils.toStringArray(result);
    }
}

isSimpleProperty

  • 判斷屬性是不是 “簡單” 屬性
public static boolean isSimpleProperty(Class<?> type) {
    Assert.notNull(type, "'type' must not be null");
    // clazz是簡單值類型 || ( clazz是數(shù)組 && clazz的組件類型為簡單值類型)
    // getComponentType:返回數(shù)組的組件類型,例如: String[] 返回 String.class峻黍,如果是非數(shù)組道宅,則返回null
    return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
}

public static boolean isSimpleValueType(Class<?> type) {
    return (Void.class != type && void.class != type &&
            (ClassUtils.isPrimitiveOrWrapper(type) ||
            Enum.class.isAssignableFrom(type) ||
            CharSequence.class.isAssignableFrom(type) ||
            Number.class.isAssignableFrom(type) ||
            Date.class.isAssignableFrom(type) ||
            Temporal.class.isAssignableFrom(type) ||
            URI.class == type ||
            URL.class == type ||
            Locale.class == type ||
            Class.class == type));
}

public static boolean isPrimitiveOrWrapper(Class<?> clazz) {
    Assert.notNull(clazz, "Class must not be null");
    // clazz為基礎(chǔ)類型 或者 clazz是基礎(chǔ)類型的封裝類
    return (clazz.isPrimitive() || isPrimitiveWrapper(clazz));
}

public static boolean isPrimitiveWrapper(Class<?> clazz) {
    Assert.notNull(clazz, "Class must not be null");
    // 檢查clazz是否為8種基礎(chǔ)類型的包裝類
    // primitiveWrapperTypeMap緩存包含8種基礎(chǔ)類型和包裝類的映射,例如:Integer.class -> int.class
    return primitiveWrapperTypeMap.containsKey(clazz);
}

static {
    primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
    primitiveWrapperTypeMap.put(Byte.class, byte.class);
    primitiveWrapperTypeMap.put(Character.class, char.class);
    primitiveWrapperTypeMap.put(Double.class, double.class);
    primitiveWrapperTypeMap.put(Float.class, float.class);
    primitiveWrapperTypeMap.put(Integer.class, int.class);
    primitiveWrapperTypeMap.put(Long.class, long.class);
    primitiveWrapperTypeMap.put(Short.class, short.class);
    primitiveWrapperTypeMap.put(Void.class, void.class);
}

containsBean

  • 檢測是否存在與 propertyName 相關(guān)的 bean 或 BeanDefinition是否存在籍救。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    @Override
    public boolean containsBean(String name) {
        // 1.將name轉(zhuǎn)換為真正的beanName
        String beanName = transformedBeanName(name);
        // 2.檢查singletonObjects緩存和beanDefinitionMap緩存中是否存在beanName
        if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
            // 3.name不帶&前綴习绢,或者是FactoryBean,則返回true
            return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
        }
        // Not found -> check parent.
        // 4.沒有找到則檢查parentBeanFactory
        BeanFactory parentBeanFactory = getParentBeanFactory();
        return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
    }
}

autowireByType

  • 解析 autowireByType 的注入
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        //獲取的屬性類型轉(zhuǎn)換器
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
        //用來存放解析的要注入的屬性名
        Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
        //獲取要注入的屬性名稱(非簡單屬性(8種原始類型、字符闪萄、URL等都是簡單屬性))
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            try {
                //獲取指定屬性名稱的屬性Descriptor(Descriptor用來記載屬性的getter setter type等情況)
                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類型的屬性進(jìn)行裝配注入梧却,技術(shù)上沒法實現(xiàn),并且沒有意義
                //即如果屬性類型為 Object败去,則忽略放航,不做解析
                if (Object.class != pd.getPropertyType()) {
                    // 獲取指定屬性的set方法,封裝成MethodParameter(必須有set方法才能通過屬性來注入)
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                    // Do not allow eager init for type matching in case of a prioritized post-processor.
                    // 對于繼承了PriorityOrdered的post-processor圆裕,不允許立即初始化(熱加載)
                    boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
                    // 創(chuàng)建一個要被注入的依賴描述广鳍,方便提供統(tǒng)一的訪問
                    // 將MethodParameter的方法參數(shù)索引信息封裝成DependencyDescriptor
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                    //根據(jù)容器的BeanDefinition解析依賴關(guān)系,返回所有要被注入的Bean實例
                    //解析當(dāng)前屬性所匹配的bean實例吓妆,并把解析到的bean實例的beanName存儲在autowiredBeanNames中
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                    if (autowiredArgument != null) {
                        // 將解析出的 bean 存入到屬性值列表pvs中
                        pvs.add(propertyName, autowiredArgument);
                    }
                    for (String autowiredBeanName : autowiredBeanNames) {
                        // 注冊依賴關(guān)系赊时,beanName依賴autowiredBeanName
                        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);
            }
        }
    }
}
  • 尋找 bw 中需要依賴注入的屬性。

  • 解析當(dāng)前屬性所匹配的 bean 實例行拢,并把解析到的 bean 實例的 beanName 存儲在 autowiredBeanNames 中祖秒。

  • 注冊依賴關(guān)系,beanName 依賴 autowiredBeanName舟奠。

applyPropertyValues

  • 最終將屬性注入到Bean的Wrapper實例里竭缝,這里的注入主要是供顯式配置了autowiredbyName或者ByType的屬性注入。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }

        if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
            //設(shè)置安全上下文沼瘫,JDK安全機制
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }

        MutablePropertyValues mpvs = null;
        List<PropertyValue> original;
        // 1.獲取屬性值列表
        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            // 1.1 如果mpvs中的值已經(jīng)被轉(zhuǎn)換為對應(yīng)的類型抬纸,那么可以直接設(shè)置到BeanWrapper中
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    bw.setPropertyValues(mpvs);
                    return;
                }
                catch (BeansException ex) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
                }
            }
            original = mpvs.getPropertyValueList();
        }
        else {
            // 1.2 如果pvs并不是使用MutablePropertyValues封裝的類型,那么直接使用原始的屬性獲取方法
            original = Arrays.asList(pvs.getPropertyValues());
        }

        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
        // 2.1 獲取對應(yīng)的解析器
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // Create a deep copy, resolving any references for values.
        // 2.2 創(chuàng)建深層拷貝副本耿戚,用于存放解析后的屬性值
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        // 3.遍歷屬性湿故,將屬性轉(zhuǎn)換為對應(yīng)類的對應(yīng)屬性的類型
        for (PropertyValue pv : original) {
            if (pv.isConverted()) {
                // 3.1 如果pv已經(jīng)包含轉(zhuǎn)換的值,則直接添加到deepCopy
                deepCopy.add(pv);
            }
            else {
                // 3.2 否則溅话,進(jìn)行轉(zhuǎn)換
                // 3.2.1 拿到pv的原始屬性名和屬性值
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                    Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
                    if (writeMethod == null) {
                        throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
                    }
                    originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
                }
                // 3.2.2 使用解析器解析原始屬性值
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                // 3.2.3 判斷該屬性是否可轉(zhuǎn)換
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    // 3.2.4 如果可轉(zhuǎn)換晓锻,則轉(zhuǎn)換指定目標(biāo)屬性的給定值
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
                // 3.2.5 在合并的BeanDefinition中存儲轉(zhuǎn)換后的值,以避免為每個創(chuàng)建的bean實例重新轉(zhuǎn)換
                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();
        }

        // Set our (possibly massaged) deep copy.
        try {
            // 4.設(shè)置bean的屬性值為deepCopy
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }
}

initializeBean

對bean進(jìn)行初始化

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        // 1.激活A(yù)ware方法
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 2.在初始化前應(yīng)用BeanPostProcessor的postProcessBeforeInitialization方法飞几,允許對bean實例進(jìn)行包裝
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 3.調(diào)用初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            // 4.在初始化后應(yīng)用BeanPostProcessor的postProcessAfterInitialization方法砚哆,允許對bean實例進(jìn)行包裝
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        // 5.返回wrappedBean
        return wrappedBean;
    }
}

invokeAwareMethods

  • 激活 Aware方法
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    private void invokeAwareMethods(final String beanName, final Object bean) {
        if (bean instanceof Aware) {
            // BeanNameAware: 實現(xiàn)此接口的類想要拿到beanName,因此我們在這邊賦值給它
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            // BeanClassLoaderAware:實現(xiàn)此接口的類想要拿到beanClassLoader屑墨,因此我們在這邊賦值給它
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            // BeanFactoryAware: 實現(xiàn)此接口的類想要拿到 BeanFactory躁锁,因此我們在這邊賦值給它
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }
}

如果對 Spring 比較熟悉的同學(xué)應(yīng)該知道,以 Aware 為結(jié)尾的類都是一些擴展接口卵史,用于提供給開發(fā)者獲取到 BeanFactory 中的一些屬性或?qū)ο蟆?/p>

applyBeanPostProcessorsBeforeInitialization

  • 在初始化前應(yīng)用后置處理器 BeanPostProcessor 的 postProcessBeforeInitialization 方法战转,允許對 bean 實例進(jìn)行包裝。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        // 1.遍歷所有注冊的BeanPostProcessor實現(xiàn)類以躯,調(diào)用postProcessBeforeInitialization方法
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 2.在bean初始化方法執(zhí)行前槐秧,調(diào)用postProcessBeforeInitialization方法
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }
}

postProcessBeforeInitialization

在 bean 初始化前啄踊,調(diào)用所有 BeanPostProcessors 的 postProcessBeforeInitialization 方法,這個在很早之前就說過了刁标。這邊提一個比較重要的實現(xiàn)類:ApplicationContextAwareProcessor颠通。

class ApplicationContextAwareProcessor implements BeanPostProcessor {

    private final ConfigurableApplicationContext applicationContext;

    private final StringValueResolver embeddedValueResolver;

    @Override
    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
            return bean;
        }

        AccessControlContext acc = null;

        if (System.getSecurityManager() != null) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            // 調(diào)用Aware接口
            invokeAwareInterfaces(bean);
        }

        return bean;
    }

    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        // ApplicationContextAware:實現(xiàn)此接口的類想要拿到ApplicationContext,因此我們在這邊賦值給它
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
}

我們經(jīng)常通過實現(xiàn) ApplicationContextAware 接口來拿到 ApplicationContext膀懈,我們之所以能拿到 ApplicationContext顿锰,就是在這邊被賦值的。

invokeInitMethods

  • 調(diào)用初始化方法
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
        //如果當(dāng)前bean是 InitializingBean類型的&&afterPropertiesSet這個方法沒有注冊為外部管理的初始化方法
        //就回調(diào)afterPropertiesSet方法
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            // 調(diào)用afterPropertiesSet方法
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            //如果設(shè)置了initMethod方法的話也會執(zhí)行用戶配置的初始話方法
            //并且這個類不是 InitializingBean類型和不是afterPropertiesSet方法 启搂;
            //才能執(zhí)行用戶配置的方法
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                // 調(diào)用自定義初始化方法
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }
}

invokeCustomInitMethod

  • 調(diào)用自定義初始化方法
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {
        // 1.拿到初始化方法的方法名
        String initMethodName = mbd.getInitMethodName();
        Assert.state(initMethodName != null, "No init method set");
        // 2.根據(jù)方法名拿到方法
        Method initMethod = (mbd.isNonPublicAccessAllowed() ?
                BeanUtils.findMethod(bean.getClass(), initMethodName) :
                ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

        if (initMethod == null) {
            // 3.如果不存在initMethodName對應(yīng)的方法硼控,并且是強制執(zhí)行初始化方法(默認(rèn)為強制), 則拋出異常
            if (mbd.isEnforceInitMethod()) {
                throw new BeanDefinitionValidationException("Could not find an init method named '" +
                        initMethodName + "' on bean with name '" + beanName + "'");
            }
            else {
                // 如果設(shè)置了非強制,找不到則直接返回
                if (logger.isTraceEnabled()) {
                    logger.trace("No default init method named '" + initMethodName +
                            "' found on bean with name '" + beanName + "'");
                }
                // Ignore non-existent default lifecycle methods.
                return;
            }
        }

        if (logger.isTraceEnabled()) {
            logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
        }
        Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
        // 4.調(diào)用初始化方法
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                ReflectionUtils.makeAccessible(methodToInvoke);
                return null;
            });
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                        methodToInvoke.invoke(bean), getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                InvocationTargetException ex = (InvocationTargetException) pae.getException();
                throw ex.getTargetException();
            }
        }
        else {
            try {
                ReflectionUtils.makeAccessible(methodToInvoke);
                methodToInvoke.invoke(bean);
            }
            catch (InvocationTargetException ex) {
                throw ex.getTargetException();
            }
        }
    }
}

applyBeanPostProcessorsAfterInitialization

  • 在初始化后應(yīng)用BeanPostProcessor的postProcessAfterInitialization方法胳赌,允許對bean實例進(jìn)行包裝牢撼。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        // 1.遍歷所有注冊的BeanPostProcessor實現(xiàn)類,調(diào)用postProcessAfterInitialization方法
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 2.在bean初始化后匈织,調(diào)用postProcessAfterInitialization方法
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                // 3.如果返回null浪默,則不會調(diào)用后續(xù)的BeanPostProcessors
                return result;
            }
            result = current;
        }
        return result;
    }
}

registerDisposableBeanIfNecessary

  • 注冊用于銷毀的bean牡直,執(zhí)行銷毀操作的有三種:自定義destroy方法缀匕、DisposableBean接口、DestructionAwareBeanPostProcessor碰逸。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
        // 1.mbd的scope不是prototype && 給定的bean需要在關(guān)閉時銷毀
        if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
            if (mbd.isSingleton()) {
                // Register a DisposableBean implementation that performs all destruction
                // work for the given bean: DestructionAwareBeanPostProcessors,
                // DisposableBean interface, custom destroy method.
                // 2.單例模式下注冊用于銷毀的bean到disposableBeans緩存乡小,執(zhí)行給定bean的所有銷毀工作:
                // DestructionAwareBeanPostProcessors,DisposableBean接口饵史,自定義銷毀方法
                // 2.1 DisposableBeanAdapter:使用DisposableBeanAdapter來封裝用于銷毀的bean
                registerDisposableBean(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
            else {
                // 3.自定義scope處理
                // A bean with a custom scope...
                Scope scope = this.scopes.get(mbd.getScope());
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
                }
                scope.registerDestructionCallback(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
        }
    }
}

requiresDestruction

  • 判斷給定的 bean 是否需要在關(guān)閉時銷毀
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
        // 1.DisposableBeanAdapter.hasDestroyMethod(bean, mbd):判斷bean是否有destroy方法
        // 2.hasDestructionAwareBeanPostProcessors():判斷當(dāng)前BeanFactory是否注冊過DestructionAwareBeanPostProcessor
        // 3.DisposableBeanAdapter.hasApplicableProcessors:是否存在適用于bean的DestructionAwareBeanPostProcessor
        return (bean.getClass() != NullBean.class &&
                (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
                        DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
    }
}

hasDestroyMethod

  • DisposableBeanAdapter.hasDestroyMethod(bean, mbd):判斷 bean 是否有 destroy 方法满钟。
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {

    public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
        if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
            // 1.如果bean實現(xiàn)了DisposableBean接口 或者 bean是AutoCloseable實例,則返回true
            return true;
        }
        // 2.拿到bean自定義的destroy方法名
        String destroyMethodName = beanDefinition.getDestroyMethodName();
        if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
            // 3.如果自定義的destroy方法名為“(inferred)”(該名字代表需要我們自己去推測destroy的方法名)胳喷,
            // 則檢查該bean是否存在方法名為“close”或“shutdown”的方法湃番,如果存在,則返回true
            return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
                    ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
        }
        // 4.如果destroyMethodName不為空吭露,則返回true
        return StringUtils.hasLength(destroyMethodName);
    }
}

如果 bean 實現(xiàn)了 DisposableBean 接口或 bean 是 AutoCloseable 實例吠撮,則返回 true,因為這兩個接口都有關(guān)閉的方法

hasApplicableProcessors

  • DisposableBeanAdapter.hasApplicableProcessors:是否存在適用于 bean 的 DestructionAwareBeanPostProcessor讲竿。
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {

    public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
        if (!CollectionUtils.isEmpty(postProcessors)) {
            // 1.遍歷所有的BeanPostProcessor
            for (BeanPostProcessor processor : postProcessors) {
                // 2.如果processor是DestructionAwareBeanPostProcessor
                if (processor instanceof DestructionAwareBeanPostProcessor) {
                    DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
                    if (dabpp.requiresDestruction(bean)) {
                        // 3.如果給定的bean實例需要通過此后處理器進(jìn)行銷毀泥兰,則返回true
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

DisposableBeanAdapter

  • 使用 DisposableBeanAdapter 來封裝用于銷毀的 bean。
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {

    public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
            List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {

        Assert.notNull(bean, "Disposable bean must not be null");
        this.bean = bean;
        this.beanName = beanName;
        // 1.判斷bean是否需要調(diào)用DisposableBean的destroy方法
        this.invokeDisposableBean =
                (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
        this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
        this.acc = acc;
        // 2.拿到自定義的destroy方法名
        String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
        if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
                !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
            this.destroyMethodName = destroyMethodName;
            // 3.拿到自定義的destroy方法
            Method destroyMethod = determineDestroyMethod(destroyMethodName);
            if (destroyMethod == null) {
                if (beanDefinition.isEnforceDestroyMethod()) {
                    // 4.如果destroy方法名為空题禀,并且enforceDestroyMethod為true鞋诗,則拋出異常
                    throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
                            destroyMethodName + "' on bean with name '" + beanName + "'");
                }
            }
            else {
                // 5.拿到destroy方法的參數(shù)類型數(shù)組
                Class<?>[] paramTypes = destroyMethod.getParameterTypes();
                if (paramTypes.length > 1) {
                    // 6.如果destroy方法的參數(shù)大于1個,則拋出異常
                    throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
                            beanName + "' has more than one parameter - not supported as destroy method");
                }
                else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
                    // 7.如果destroy方法的參數(shù)為1個迈嘹,并且該參數(shù)的類型不為boolean削彬,則拋出異常
                    throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
                            beanName + "' has a non-boolean parameter - not supported as destroy method");
                }
                destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
            }
            //賦值給this.destroyMethod
            this.destroyMethod = destroyMethod;
        }
        // 8.查找DestructionAwareBeanPostProcessors,并賦值給this.beanPostProcessors
        this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
    }
}

inferDestroyMethodIfNecessary

  • 拿到自定義的 destroy 方法名。
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {

    @Nullable
    private String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
        // 1.拿到beanDefinition的destroy方法名
        String destroyMethodName = beanDefinition.getDestroyMethodName();
        // 2.如果destroy方法名為“(inferred)”|| destroyMethodName為null融痛,并且bean是AutoCloseable實例
        if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
                (destroyMethodName == null && bean instanceof AutoCloseable)) {
            // Only perform destroy method inference or Closeable detection
            // in case of the bean not explicitly implementing DisposableBean
            // 3.如果bean沒有實現(xiàn)DisposableBean接口糕篇,則嘗試推測destroy方法的名字
            if (!(bean instanceof DisposableBean)) {
                try {
                    // 4.嘗試在bean中尋找方法名為close的方法作為destroy方法
                    return bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
                }
                catch (NoSuchMethodException ex) {
                    try {
                        // 5.嘗試在bean中尋找方法名為close的方法作為shutdown方法
                        return bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
                    }
                    catch (NoSuchMethodException ex2) {
                        // no candidate destroy method found
                    }
                }
            }
            // 6.如果沒有找到,則返回null
            return null;
        }
        return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
    }
}

filterPostProcessors

  • 查找 DestructionAwareBeanPostProcessors酌心,并賦值給 beanPostProcessors拌消。
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {

    @Nullable
    private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
        List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
        if (!CollectionUtils.isEmpty(processors)) {
            filteredPostProcessors = new ArrayList<>(processors.size());
            // 1.遍歷所有的BeanPostProcessor
            for (BeanPostProcessor processor : processors) {
                // 2.如果processor是DestructionAwareBeanPostProcessor
                if (processor instanceof DestructionAwareBeanPostProcessor) {
                    DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
                    if (dabpp.requiresDestruction(bean)) {
                        // 3.如果給定的bean實例需要通過此后處理器進(jìn)行銷毀,則添加到filteredPostProcessors
                        filteredPostProcessors.add(dabpp);
                    }
                }
            }
        }
        return filteredPostProcessors;
    }
}

總結(jié)

至此安券,finishBeanFactoryInitialization 方法解析完畢墩崩,在 finishBeanFactoryInitialization 方法中,我們主要做了以下操作:

  • 將之前解析的 BeanDefinition 進(jìn)一步處理侯勉,將有父 BeanDefinition 的進(jìn)行合并鹦筹,獲得 MergedBeanDefinition
  • 嘗試從緩存獲取 bean 實例
  • 處理特殊的 bean —— FactoryBean 的創(chuàng)建
  • 創(chuàng)建 bean 實例
  • 循環(huán)引用的處理
  • bean 實例屬性填充
  • bean 實例的初始化
  • BeanPostProcessor 的各種擴展應(yīng)用

finishBeanFactoryInitialization 方法解析的結(jié)束,也標(biāo)志著 Spring IoC 整個構(gòu)建過程中址貌,重要的內(nèi)容基本都已經(jīng)解析完畢铐拐。

參考:
https://zhuanlan.zhihu.com/p/83491006

https://www.imooc.com/article/37039?block_id=tuijian_wz

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市练对,隨后出現(xiàn)的幾起案子遍蟋,更是在濱河造成了極大的恐慌,老刑警劉巖螟凭,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虚青,死亡現(xiàn)場離奇詭異,居然都是意外死亡螺男,警方通過查閱死者的電腦和手機棒厘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來下隧,“玉大人奢人,你說我怎么就攤上這事∠海” “怎么了何乎?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長迫筑。 經(jīng)常有香客問我宪赶,道長,這世上最難降的妖魔是什么脯燃? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任搂妻,我火速辦了婚禮,結(jié)果婚禮上辕棚,老公的妹妹穿的比我還像新娘欲主。我一直安慰自己邓厕,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布扁瓢。 她就那樣靜靜地躺著详恼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪引几。 梳的紋絲不亂的頭發(fā)上昧互,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機與錄音伟桅,去河邊找鬼敞掘。 笑死,一個胖子當(dāng)著我的面吹牛楣铁,可吹牛的內(nèi)容都是我干的玖雁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼盖腕,長吁一口氣:“原來是場噩夢啊……” “哼赫冬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溃列,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤劲厌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后哭廉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脊僚,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年遵绰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片增淹。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡椿访,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出虑润,到底是詐尸還是另有隱情成玫,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布拳喻,位于F島的核電站哭当,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冗澈。R本人自食惡果不足惜钦勘,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望亚亲。 院中可真熱鬧彻采,春花似錦腐缤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至特笋,卻和暖如春剃浇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猎物。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工偿渡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霸奕。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓溜宽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親质帅。 傳聞我的和親對象是個殘疾皇子适揉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359