BeanPostProcessor接口家族体系

2022/05/06 springboot专题 共 16140 字,约 47 分钟
闷骚的程序员

1. BeanPostProcessor家族系列

BeanPostProcessor在spring中统称为bean的后置处理器,说白了只要注册到spring容器中的BeanPostProcessor的实例对象,都将在bean的生命周期的不同阶段干预bean的相关行为。
BeanPostProcessor接口的继承体系大致如下:

BeanPostProcessor的主要子接口如上图所示,不同的接口实例作用于Bean的不同生命周期阶段。
Bean的实例化阶段是通过反射创建Bean的实例对象,其早于Bean的初始化阶段,最后才是Bean的销毁阶段。

2. Bean的实例化阶段

在spring中,Bean的实例化阶段指的是创建Bean的过程,此时Bean正在通过反射或者其他操作被创建,其属性还没有被填充。

2.1 InstantiationAwareBeanPostProcessor

注意,spring并不推荐开发人员使用这个接口,因为使用这个接口其实是相当于给了用户自定义一个代理对象的机会,spring会直接使用该代理对象而不会对该对象进行属性维护等操作。 InstantiationAwareBeanPostProcessor接口是BeanPostProcessor的子接口,该接口源码如下:

package org.springframework.beans.factory.config;

import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    // 该方法在目标bean被实例化之前回调,返回值是Object类型,一般在此处可以返回目标bean的一个代理对象来代替真实的目标bean对象,并且被正常放入spring容器中。
    // 返回值如果不是null,后续该目标bean将不再被实例化,只会回调执行第二个方法 postProcessAfterInstantiation ,其他方法不会调用。
    // 否则,如果返回的是null的话,则流程按照正常bean的实例化流程走。
    Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;

    // 在目标bean对象被实例化之后,并且属性还没有被填充的时候调用。
    // 返回值是boolean类型,返回true时候,表示bean的属性需要被赋值;返回false表示跳过bean的属性赋值,并且第三个方法postProcessPropertyValues不会被回调。
    boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;

    // 在属性被设置到目标bean之前,对属性值进行修改
    // @Autowired、@Resource等就是根据这个回调来实现最终注入到依赖属性中的真实值的
    PropertyValues postProcessPropertyValues(PropertyValues var1, PropertyDescriptor[] var2, Object bean, String beanName) throws BeansException;
}

调用源码分析:
前面的调用流程都和BeanPostProcessor中的源码流程一致,这里直接从createBean方法开始: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Creating instance of bean '" + beanName + "'");
        }

        RootBeanDefinition mbdToUse = mbd;
        // 马上要实例化bean了,确保bean class已经被成功加载。
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        try {
            mbdToUse.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException var9) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
        }

        Object beanInstance;
        try {
            
            // 我们可以看到,在正式开始doCreateBean之前,调用了这个方法。
            // 这个方法主要用来解决Bean的实例化之前的处理逻辑的。
            // resolveBeforeInstantiation方法主要是给InstantiationAwareBeanPostProcessor后置处理器返回一个Bean代理对象的机会
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            // 如果返回的不为空,说明已经实例化了(即通过InstantiationAwareBeanPostProcessor的before方法获取到bean了),则直接返回;为空的话,继续走下面的正常流程doCreateBean
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var10) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
        }

        try {
            // 如果上面调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法返回的是个null值的话,说明bean实例化前置没有被增量代理,则走正常的doCreateBean流程
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Finished creating instance of bean '" + beanName + "'");
            }

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
        }
    }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory,注意,beforeInstantiationResolved属性值默认为null:

    @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        // beforeInstantiationResolved属性值默认为null, 这意味着任何一个bean在实例化之前都会进入到这个条件里面
        // 当这段逻辑成功返回一个非null的对象后,beforeInstantiationResolved属性值会被设置为true,否则会被设置为false。
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // 判断是否有InstantiationAwareBeanPostProcessor处理器
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = this.determineTargetType(beanName, mbd);
                
                if (targetType != null) {
                    // 执行InstantiationAwareBeanPostProcessor处理器中的postProcessBeforeInstantiation方法
                    bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        // 如果bean已经被上述的前置处理器实例化了,
                        // 则跳过其他步骤,直接执行BeanPostProcessor处理器中的postProcessAfterInitialization方法进行初始化
                        bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }

            // 如果bean不为null,设置beforeInstantiationResolved属性值为true;表示InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法被成功调用了,返回了一个替代对象
            mbd.beforeInstantiationResolved = bean != null;
        }

        return bean;
    }

如果bean没有被增量代理的话,则和BeanPostProcessor中分析的一样,执行正常的doCreateBean流程:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        // 实例化Bean开始
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            // 实例化bean,bean实例化的核心方法就是这里,但InstantiationAwareBeanPostProcessor的触发却不在这个方法里。
            // 相反,下面要将的SmartInstantiationAwareBeanPostProcessor接口的回调将会在该方法里面执行。
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
        // 实例化bean结束
        

        Object var7 = mbd.postProcessingLock;
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }

        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }

            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
            // 为当前bean填充属性值,这里要特别注意,InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法就是在填充属性时触发回调的,而不是在bean的创建过程中。
            this.populateBean(beanName, mbd, instanceWrapper);
            
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.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 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

populateBean,填充bean的属性,并且在填充前先回调InstantiationAwareBeanPostProcessor接口的实例化后置方法postProcessAfterInstantiation:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
        } else {
            // 获取所有的InstantiationAwareBeanPostProcessor 
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();

                while(var4.hasNext()) {
                    InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
                    // 调用postProcessAfterInstantiation方法,如果返回false, 则populateBean方法直接返回,后续赋值操作不再进行
                    if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        return;
                    }
                }
            }

            // 开始为属性赋值,比如@Autowired注解的
            PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
            int resolvedAutowireMode = mbd.getResolvedAutowireMode();
            if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                if (resolvedAutowireMode == 1) {
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }

                if (resolvedAutowireMode == 2) {
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }

                pvs = newPvs;
            }

            boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
            boolean needsDepCheck = mbd.getDependencyCheck() != 0;
            PropertyDescriptor[] filteredPds = null;
            if (hasInstAwareBpps) {
                if (pvs == null) {
                    pvs = mbd.getPropertyValues();
                }

                PropertyValues pvsToUse;
                for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
                    
                    // 如果postProcessAfterInstantiation方法返回true,则获取所有的InstantiationAwareBeanPostProcessor
                    InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
                    pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }

                        // 在此处回调执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法,使用该方法返回的PropertyValues作为bean的属性值。
                        pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                }
            }

            if (needsDepCheck) {
                if (filteredPds == null) {
                    filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }

                this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
            }

            if (pvs != null) {
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }

        }
    }

分析InstantiationAwareBeanPostProcessor的触发流程,其实和分析BeanPostProcessor的源码流程是严重耦合在一起的。结合两者的执行流程,其大致逻辑图如下:

2.2 SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor是InstantiationAwareBeanPostProcessor接口的子接口,主要作用也是介入目标bean对象的实例化过程中需要回调处理某些事情。
该接口是InstantiationAwareBeanPostProcessor接口的一个扩展接口,主要用于spring框架内部,对于开发者来说不用过多关注。
该接口源码如下:

package org.springframework.beans.factory.config;

import java.lang.reflect.Constructor;
import org.springframework.beans.BeansException;

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
    
    // 用于预测Bean的类型,返回值表示第一个预测成功的bean class类型;如果不能预测的话则返回null。
    // 主要用于BeanDefinition无法确定Bean类型的时候调用该方法来确定类型。
    Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException;

    // 用于在通过反射来创建bean对象的时候,选择合适的构造器。
    // 比如目标bean有多个构造器,可以通过实现这个方法来选择合适的构造器用于后期实例化目标bean。
    // 该方法用于在InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间进行回调。
    // 如果postProcessBeforeInstantiation方法返回了一个新的实例代替了原本应该生成的实例,那么该方法会被忽略。
    Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;

    // 该方法主要用于解决循环依赖的问题。
    // 比如ReferenceA实例内部有ReferenceB的引用,ReferenceB实例内部有ReferenceA的引用。
    // 首先先实例化ReferenceA,实例化完成之后提前把这个bean暴露在ObjectFactory中,然后populate属性,这个时候发现需要ReferenceB。
    // 然后去实例化ReferenceB,在实例化ReferenceB的时候它需要ReferenceA的实例才能继续,这个时候就会去ObjectFactory中找出了ReferenceA实例,ReferenceB顺利实例化。
    // ReferenceB实例化之后,ReferenceA的populate属性过程也成功完成,注入了ReferenceB实例。
    // 提前把这个bean暴露在ObjectFactory中,这个ObjectFactory获取的实例就是通过getEarlyBeanReference方法得到的。
    Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
}

触发源码分析:
上面分析了,在doCreateBean方法中,通过createBeanInstance方法来创建真正的bean实例,SmartInstantiationAwareBeanPostProcessor接口的触发回调就是在这个方法里面进行的:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 确保拿到的class是可以正确执行的bean class
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        } else {
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return this.obtainFromSupplier(instanceSupplier, beanName);
            } else if (mbd.getFactoryMethodName() != null) {
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            } else {
                
                
                // Spring会将解析好的构造函数放到缓存中,每次获取之前先到缓存中获取。
                boolean resolved = false; // 构造函数是否或工厂函数是否已解析
                boolean autowireNecessary = false; // 构造函数是否需要参数
                if (args == null) {
                    Object var8 = mbd.constructorArgumentLock;
                    synchronized(mbd.constructorArgumentLock) {
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }

                if (resolved) {
                    // autowireConstructor:调用构造函数有参数实例化
                    // 调用默认构造函数实例化
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
                    // !!!核心:调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors确定用于给定bean的候选构造函数。
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    
                    // 以下情况符合其一即可进入
                    // 1、存在可选构造方法
                    // 2、自动装配模型为构造函数自动装配
                    // 3、给BeanDefinition中设置了构造参数值
                    // 4、有参与构造函数参数列表的参数
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                        
                        // 找出最合适的默认构造方法
                        ctors = mbd.getPreferredConstructors();
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            }
        }
    }

determineConstructorsFromBeanPostProcessors方法,选择最合适的构造函数:

    @Nullable
    protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
        // 如果beanClass存在并且有InstantiationAwareBeanPostProcessors
        if (beanClass != null && this.hasInstantiationAwareBeanPostProcessors()) {
            
            // 获取所有的SmartInstantiationAwareBeanPostProcessor
            Iterator var3 = this.getBeanPostProcessorCache().smartInstantiationAware.iterator();

            while(var3.hasNext()) {
                SmartInstantiationAwareBeanPostProcessor bp = (SmartInstantiationAwareBeanPostProcessor)var3.next();
                
                // 遍历执行SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法,只要有一个方法返回了构造器,则直接返回,终止遍历。
                Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
                if (ctors != null) {
                    return ctors;
                }
            }
        }

        return null;
    }

3. Bean的初始化阶段

Bean的初始化阶段是指Bean实例化完成后,对Bean进行属性填充,以及初始化方法调用的阶段。

3.1 MergedBeanDefinitionPostProcessor

MergedBeanDefinitionPostProcessor接口继承BeanPostProcessor,在合并Bean定义之后调用。其源码如下:

package org.springframework.beans.factory.support;

import org.springframework.beans.factory.config.BeanPostProcessor;

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
    
    // 该方法在合并Bean定义之后进行回调
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}

3.2 BeanPostProcessor

BeanPostProcessor接口是这个继承体系的顶层接口,其中的方法也是整个继承体系中的核心方法。这个接口已经有专门的文章进行讲解。
请参考:beanPostProcessor简介

4. Bean的销毁阶段

Bean的销毁阶段指的就是Bean在spring容器销毁时执行的阶段。

4.1 DestructionAwareBeanPostProcessor

DestructionAwareBeanPostProcessor接口继承BeanPostProcessor接口,bean在spring容器销毁前进行调用。其源码如下:

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
    
    // bean在销毁之前调用
    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

    // 在bean销毁之前进行回调,决定bean是否要被销毁。
    // 返回值是Boolean类型,如果返回true,则先回调上面的postProcessBeforeDestruction方法;如果返回false,则不进行销毁。
    boolean requiresDestruction(Object bean);
}

文档信息

Search

    Table of Contents