由Spring的拓展點BeanPostProcessor來看Spring建立Bean的流程

一.BeanPostProcessor是什麼

public interface BeanPostProcessor {

    /**
     * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     */
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    /**
     * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
     * instance and the objects created by the FactoryBean (as of Spring 2.0). The
     * post-processor can decide whether to apply to either the FactoryBean or created
     * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
     * <p>This callback will also be invoked after a short-circuiting triggered by a
     * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
     * in contrast to all other BeanPostProcessor callbacks.
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     * @see org.springframework.beans.factory.FactoryBean
     */
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

BeanPostProcessor是Spring容器的一個擴展點,能夠進行自定義的實例化、初始化、依賴裝配、依賴檢查等流程,便可以覆蓋默認的實例化,也能夠加強初始化、依賴注入、依賴檢查等流程,其javadoc有以下描述:java

e.g. checking for marker interfaces or wrapping them with proxies.

大致意思是能夠檢查相應的標識接口完成一些自定義功能實現,如包裝目標對象到代理對象。spring

咱們能夠看到BeanPostProcessor一共有兩個回調方法postProcessBeforeInitialization和postProcessAfterInitialization,那這兩個方法會在什麼Spring執行流程中的哪一個步驟執行呢?還有目前Spring提供哪些相應的實現呢?app

Spring還提供了BeanPostProcessor一些其餘接口實現,來完成除實例化外的其餘功能,後續詳細介紹。ide

二.經過Spring源碼看BeanPostProcessor的做用

ApplicationContext繼承圖

AbstractApplicationContext內部使用DefaultListableBeanFactory,且DefaultListableBeanFactory繼承AbstractAutowireCapableBeanFactory,所以咱們此處分析AbstractAutowireCapableBeanFactory便可。post

AbstractAutowireCapableBeanFactory裏面建立bean的入口是createBean方法:ui

@Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;
        //1.解析bean的class
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // 2.方法重載的準備
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //3.這裏執行BeanPostProcessor的第一個擴展點(只有InstantiationAwareBeanPostProcessor接口的實現纔會被調用)
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                //4.若是執行第一個擴展點以後得到的bean不爲空的時候,直接返回這個bean,就不作下面的操做
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
        //5.這裏是Spring容器執行建立bean的主要流程
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }

AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation的方法:this

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    //3.1 執行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回調方法  
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        //3.2 若是3.1獲得的bean不爲空的話,執行InstantiationAwareBeanPostProcessor的postProcessAfterInitialization回調方法 ,若是這一步是空的話,則步驟3之後的流程
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

經過如上代碼能夠進行實例化的預處理(自定義實例化bean,如建立相應的代理對象)和後處理(如進行自定義實例化的bean的依賴裝配)。spa

AbstractAutowireCapableBeanFactory的doCreateBean方法代碼以下:debug

//這段代碼是執行建立bean的主要流程的
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        // 6.經過BeanWrapper實例化Bean   
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        mbd.resolvedTargetType = beanType;

        // Allow post-processors to modify the merged bean definition.
        //七、執行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition流程(主要的功能是合併BeanDefination)
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    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.
        // 8.及早暴露單例Bean引用,從而容許setter注入方式的循環引用  
        // 判斷這個bean是否存在循環依賴的狀況
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            //若是須要提早暴露bean(存在了循環依賴)
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            // 把這個提早暴露的bean(只進行了實例化,可是沒有注入屬性)註冊到singletonFactory中
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    //這裏調用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference返回一個須要暴露的Bean(例如包裝目標對象到代理對象)
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //9.在這裏組裝bean的依賴
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                //10.這裏進行的是初始化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);
            }
        }

        if (earlySingletonExposure) {
           //11. 若是這個bean是被提早暴露過的,則經過getSingleton方法獲取bean
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                   
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        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 " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            //12.這裏註冊bean銷燬的回調
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

AbstractAutowireCapableBeanFactory的populateBean方法代碼以下:代理

//9.組裝bean
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        PropertyValues pvs = mbd.getPropertyValues();

        if (bw == null) {
            if (!pvs.isEmpty()) {
                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.
        boolean continueWithPropertyPopulation = true;
        //9.1 經過InstantiationAwareBeanPostProcessor擴展點容許自定義裝配流程(如@Autowired支持等)  
        //執行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation      
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }

        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // Add property values based on autowire by name if applicable.
            //9.2 根據BeanName或者BeanType來進行依賴注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // Add property values based on autowire by type if applicable.
            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);
        //9.3 執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues~~~~ 
        if (hasInstAwareBpps || needsDepCheck) {
            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) {
                //9.4 執行依賴檢查
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }
        //9.5 應用依賴注入
        applyPropertyValues(beanName, mbd, bw, pvs);
    }

AbstractAutowireCapableBeanFactory的initializeBean方法代碼以下:

//10 這裏執行的是初始化bean的相關工做
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        //10.1 調用Aware接口注入(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
        
        Object wrappedBean = bean;
        //10.2 執行BeanPostProcessor擴展點的postProcessBeforeInitialization執行bean初始化前的回調
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
       
        //10.3 執行初始化回調(1 調用InitializingBean的afterPropertiesSet  2 調用自定義的init-method)
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        //10.4 執行BeanPostProcessor擴展點的postProcessAfterInitialization進行修改實例化Bean  
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

三.總結

經過對Spring源碼的解讀,我相信你們已經對BeanPostProcessor這個接口有了必定的瞭解。能夠看到BeanPostProcessor基本上貫穿了Spring建立bean的整個生命週期,下面咱們對BeanPostProcessor的幾個擴展點進行一下總結:
1.resolveBeanClass(mbd, beanName), 解析Bean class,若class配置錯誤將拋出CannotLoadBeanClassException;

2.mbd.prepareMethodOverrides(), 準備和驗證配置的方法注入,若驗證失敗拋出BeanDefinitionValidationException;

3 Object bean = resolveBeforeInstantiation(beanName, mbd); 第一個BeanPostProcessor擴展點,此處只執行InstantiationAwareBeanPostProcessor類型的BeanPostProcessorBean;
3.1 bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName),執行InstantiationAwareBeanPostProcessor的實例化的預處理回調方法postProcessBeforeInstantiation(自定義的實例化,如建立代理);
3.2 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);執行InstantiationAwareBeanPostProcessor的實例化的後處理回調方法postProcessAfterInitialization(如依賴注入),若是3.1處返回的Bean不爲null才執行;

4.若是3處的擴展點返回的bean不爲空,直接返回該bean,後續流程不須要執行;

5.Object beanInstance = doCreateBean(beanName, mbd, args),執行spring的建立bean實例的流程;

6 createBeanInstance(beanName, mbd, args), 實例化Bean;
6.1 instantiateUsingFactoryMethod 工廠方法實例化;
6.2 構造器實例化;
6.2.1 若是以前已經解析過構造器;
6.2.1.1 autowireConstructor:有參調用autowireConstructor實例化;
6.2.1.2 instantiateBean:無參調用instantiateBean實例化;
6.2.2 若是以前沒有解析過構造器:
6.2.2.1 經過SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors回調方法解析構造器,第二個BeanPostProcessor擴展點,返回第一個解析成功(返回值不爲null)的構造器組,如AutowiredAnnotationBeanPostProcessor實現將自動掃描經過@Autowired/@Value註解的構造器從而能夠完成構造器注入;
6.2.2.二、autowireConstructor:若是(6.2.2.1返回的不爲null,且是有參構造器,調用autowireConstructor實例化;
6.2.2.三、instantiateBean: 不然調用無參構造器實例化;

7 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);第三個BeanPostProcessor擴展點,執行Bean定義的合併,執行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition回調方法,進行bean定義的合併;

8

addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });

及早暴露單例Bean引用,從而容許setter注入方式的循環引用;
8.一、SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference,第四個BeanPostProcessor擴展點,當存在循環依賴時,經過該回調方法獲取及早暴露的Bean實例;

9 populateBean(beanName, mbd, instanceWrapper),裝配Bean依賴
9.1 InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation;第五個BeanPostProcessor擴展點,在實例化Bean以後,全部其餘裝配邏輯以前執行,若是false將阻止其餘的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation的執行和從9.2到9.5的執行,一般返回true;
9.2 autowireByName、autowireByType:根據名字和類型進行自動裝配;
9.3 InstantiationAwareBeanPostProcessor的postProcessPropertyValues:第六個BeanPostProcessor擴展點,完成其餘定製的一些依賴注入,如AutowiredAnnotationBeanPostProcessor執行@Autowired註解注入,CommonAnnotationBeanPostProcessor執行@Resource等註解的注入,PersistenceAnnotationBeanPostProcessor執行@ PersistenceContext等JPA註解的注入,RequiredAnnotationBeanPostProcessor執行@ Required註解的檢查等等;
9.4 checkDependencies:依賴檢查;
9.5 applyPropertyValues:應用明確的setter屬性注入;

10 exposedObject = initializeBean(beanName, exposedObject, mbd); 執行初始化Bean流程;
10.1 invokeAwareMethods(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware):調用一些Aware標識接口注入如BeanName、BeanFactory;
10.2 BeanPostProcessor的postProcessBeforeInitialization:第七個擴展點,在調用初始化以前完成一些定製的初始化任務,如BeanValidationPostProcessor完成JSR-303 @Valid註解Bean驗證,InitDestroyAnnotationBeanPostProcessor完成@PostConstruct註解的初始化方法調用,ApplicationContextAwareProcessor完成一些Aware接口的注入(如EnvironmentAware、ResourceLoaderAware、ApplicationContextAware),其返回值將替代原始的Bean對象;
10.3 invokeInitMethods : 調用初始化方法;
10.3.1 InitializingBean的afterPropertiesSet:調用InitializingBean的afterPropertiesSet回調方法;
10.3.2 經過xml指定的自定義init-method:調用經過xml配置的自定義init-method;
10.3.3 BeanPostProcessor的postProcessAfterInitialization:第八個擴展點AspectJAwareAdvisorAutoProxyCreator(完成xml風格的AOP配置(<aop:config>)的目標對象包裝到AOP代理對象),AnnotationAwareAspectJAutoProxyCreator(完成@Aspectj註解風格(<aop:aspectj-autoproxy> @Aspect)的AOP配置的目標對象包裝到AOP代理對象),其返回值將替代原始的Bean對象;

11 若是是earlySingleExposure,調用getSingle方法獲取Bean實例,
earlySingleExposure =(mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName))
只要單例Bean且容許循環引用(默認true)且當前單例Bean正在建立中,若是是earlySingletonExposure調用getSingleton將觸發【8】處ObjectFactory.getObject()的調用,經過【8.1】處的getEarlyBeanReference獲取相關Bean;

12 registerDisposableBeanIfNecessary(beanName, bean, mbd): 註冊Bean的銷燬方法(只有非原型Bean可註冊):
12.1 單例Bean的銷燬流程
12.1.1 DestructionAwareBeanPostProcessor的postProcessBeforeDestruction : 第九個擴展點,如:InitDestroyAnnotationBeanPostProcessor完成@PreDestroy註解的銷燬方法註冊和調用;
12.1.2 DisposableBean的destroy:註冊/調用DisposableBean的destroy銷燬方法;
12.1.3 經過xml指定的自定義destroy-method : 註冊/調用經過XML指定的destroy-method銷燬方法;
12.1.2 Scope的registerDestructionCallback:註冊自定義的Scope的銷燬回調方法,如RequestScope,SessionScope等;其流程和【12.1 單例Bean的銷燬流程同樣】

1三、到此Bean實例化、依賴注入、初始化完畢能夠返回建立好的bean了。

因而可知,BeanPostProcessor這個接口貫穿了Spring建立單例bean的整個過程,咱們在開發過程當中能夠經過定製化的BeanPostProessor來實現對bean的修改。

該博客轉載自https://www.iteye.com/topic/1122937

相關文章
相關標籤/搜索