转载

由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有如下描述:

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

大体意思是可以检查相应的标识接口完成一些自定义功能实现,如包装目标对象到代理对象。

我们可以看到BeanPostProcessor一共有两个回调方法postProcessBeforeInitialization和postProcessAfterInitialization,那这两个方法会在什么Spring执行流程中的哪个步骤执行呢?还有目前Spring提供哪些相应的实现呢?

Spring还提供了BeanPostProcessor一些其他接口实现,来完成除实例化外的其他功能,后续详细介绍。

二.通过Spring源码看BeanPostProcessor的作用

由Spring的拓展点BeanPostProcessor来看Spring创建Bean的流程

AbstractApplicationContext内部使用DefaultListableBeanFactory,且DefaultListableBeanFactory继承AbstractAutowireCapableBeanFactory,因此我们此处分析AbstractAutowireCapableBeanFactory即可。

AbstractAutowireCapableBeanFactory里面创建bean的入口是createBean方法:

@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的方法:

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的依赖装配)。

AbstractAutowireCapableBeanFactory的doCreateBean方法代码如下:

//这段代码是执行创建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.
        //7、执行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.2、autowireConstructor:如果(6.2.2.1返回的不为null,且是有参构造器,调用autowireConstructor实例化;

6.2.2.3、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.1、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的销毁流程一样】

13、到此Bean实例化、依赖注入、初始化完毕可以返回创建好的bean了。

由此可见,BeanPostProcessor这个接口贯穿了Spring创建单例bean的整个过程,我们在开发过程中可以通过定制化的BeanPostProessor来实现对bean的修改。

该博客转载自 https://www.iteye.com/topic/1122937

原文  https://segmentfault.com/a/1190000020721162
正文到此结束
Loading...