Spring的BeanPostProcessor接口详解

BeanPostProcessor的作用

bean的后置处理器是spring ioc容器管理bean最重要的一个拓展机制,通过向BeanFactory中添加自定义的BeanPostProcessor,就能够在bean的生命周期内对bean的实例化、属性注入、初始化等进行自定义修改。

例如:在bean的实例化过程,spring默认会调用bean的无参构造函数通过反射进行实例化,而开发者想自定义选择构造函数,则可以通过实现BeanPostProcessor来完成。

再或者spring的AOP,本质上也是通过BeanPostProcessor在bean实例化好后,对其进行代理增强,得到其代理类。

BeanPostProcessor接口定义

public interface BeanPostProcessor {

    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

postProcessBeforeInitialization

  • 实现该方法就能拿到实例化的bean,该方法返回结果也是一个bean,因此可以对传入的bean进行自定义修改后返回
  • 在一些bean的初始化回调前进行调用,例如InitializingBean的afterPropertiesSet方法前或者自定义的的init-method前。
  • 该方法拿到的bean是已经经过了属性填充的bean。

postProcessAfterInitialization

  • 实现该方法就能拿到实例化的bean,该方法返回结果也是一个bean,因此可以对传入的bean进行自定义修改后返回
  • 在一些bean的初始化回调后进行调用,例如InitializingBean的afterPropertiesSet方法后或者自定义的的init-method后。

BeanPostProcessor接口的执行时机

  • AbstractApplicationContext#refresh 核心方法入口
  • AbstractApplicationContext#finishBeanFactoryInitialization 初始化所有(非懒加载)单例bean
  • DefaultListableBeanFactory#preInstantiateSingletons 初始化所有(非懒加载)单例bean
  • AbstractBeanFactory#getBean 根据单例bean名称获取实例
  • AbstractBeanFactory#doGetBean 根据单例bean名称获取实例
  • AbstractAutowireCapableBeanFactory#createBean 创建bean实例
  • AbstractAutowireCapableBeanFactory#doCreateBean 创建bean实例

  • AbstractAutowireCapableBeanFactory#initializeBean 初始化bean

其中applyBeanPostProcessorsBeforeInitialization方法会调用所有实现了BeanPostProcessor接口的postProcessBeforeInitialization方法

invokeInitMethods方法调用所有实现InitializingBean接口的afterPropertiesSet方法以及自定义的初始化方法

applyBeanPostProcessorsAfterInitialization在初始化之后调用所有实现BeanPostProcessor接口的postProcessAfterInitialization方法

我们总结下BeanPostProcessor的源码上下文方法:

populateBean(beanName, mbd, instanceWrapper); // 给bean进行属性赋值
initializeBean(beanName, exposedObject, mbd)
{
    applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//bean的初始化前
    invokeInitMethods(beanName, wrappedBean, mbd); // 先执行InitializingBean接口的afterPropertiesSet方法和用户自定义的初始化
    applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//bean的初始化后
}

BeanPostProcessor的子类接口

BeanPostProcessor提供了很多非常重要的子类接口,对BeanPostProcessor只能在bean初始化阶段拓展的不足做了增强。

InstantiationAwareBeanPostProcessor

BeanPostProcessor的子接口,添加了在bean实例化前后的回调方法,同时还提供了拿到bean的属性回调方法。

postProcessBeforeInstantiation

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

通过实现该接口方法能够直接在这里自定义创建bean的实例,从而跳过spring内部实例化的过程。

调用入口:

  • AbstractApplicationContext#refresh
  • AbstractApplicationContext#finishBeanFactoryInitialization(步骤11:实例化初始化所有非懒加载的单例bean)
  • DefaultListableBeanFactory#preInstantiateSingletons
  • AbstractBeanFactory#doGetBean
  • AbstractAutowireCapableBeanFactory#createBean
  • AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
  • AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // 判断是否存在InstantiationAwareBeanPostProcessor,存在则applyBeanPostProcessorsBeforeInstantiation
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                //如果拿到的bean不为null,代表已经实例化了,直接这里执行bean的初始化过程
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

遍历AbstractBeanFactory#beanPostProcessors,如果是InstantiationAwareBeanPostProcessor,则执行postProcessBeforeInstantiation方法

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

postProcessAfterInstantiation

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    return true;
}

bean实例化紧接着对bean属性赋值过程会调用,通过实现postProcessAfterInstantiation并返回false时,则可以自定义跳过Spring内部属性的赋值操作。

调用入口:

  • AbstractApplicationContext#refresh
  • AbstractApplicationContext#finishBeanFactoryInitialization(步骤11:实例化初始化所有非懒加载的单例bean)
  • DefaultListableBeanFactory#preInstantiateSingletons
  • AbstractBeanFactory#doGetBean
  • AbstractAutowireCapableBeanFactory#createBean
  • AbstractAutowireCapableBeanFactory#doCreateBean
  • AbstractAutowireCapableBeanFactory#populateBean
  • InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

populateBean方法是bean实例化后对bean的属性赋值,在该方法内会遍历调用postProcessAfterInstantiation方法,如果返回fase则直接return,阻止后续的操作

postProcessProperties

default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    throws BeansException {
    return null;
}

bean属性赋值前,回调postProcessProperties,传递PropertyValues对象,PropertyValues中保存了bean实例对象中所有属性值的设置,通过修改PropertyValues可以修改属性值。

调用入口:

  • AbstractApplicationContext#refresh
  • AbstractApplicationContext#finishBeanFactoryInitialization(步骤11:实例化初始化所有非懒加载的单例bean)
  • DefaultListableBeanFactory#preInstantiateSingletons
  • AbstractBeanFactory#doGetBean
  • AbstractAutowireCapableBeanFactory#createBean
  • AbstractAutowireCapableBeanFactory#doCreateBean
  • AbstractAutowireCapableBeanFactory#populateBean
  • InstantiationAwareBeanPostProcessor#postProcessProperties

同postProcessAfterInstantiation一样,也是在属性赋值方法中进行回调。

重要实现类

AutowiredAnnotationBeanPostProcessor

自动注入是非常重要的一个后置器,实现的postProcessProperties会对@Autowired、@Value标注的字段、方法注入值。

Spring的Bean后置处理器之AutowiredAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor

对@Resource标注的字段和方法注入值。

Spring的Bean后置处理器之CommonAnnotationBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor的子接口。增加了3个方法。

predictBeanType

预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null。

default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
    return null;
}

determineCandidateConstructors

default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
    throws BeansException {
    return null;
}

bean实例化前,通过回调该方法,从而可以实现自定义选择构造器。

调用入口:

  • AbstractApplicationContext#refresh
  • AbstractApplicationContext#finishBeanFactoryInitialization(步骤11:实例化初始化所有非懒加载的单例bean)
  • DefaultListableBeanFactory#preInstantiateSingletons
  • AbstractBeanFactory#doGetBean
  • AbstractAutowireCapableBeanFactory#createBean
  • AbstractAutowireCapableBeanFactory#doCreateBean
  • AbstractAutowireCapableBeanFactory#createBeanInstance
  • AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors

遍历SmartInstantiationAwareBeanPostProcessor,调用determineCandidateConstructors返回构造函数。

@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
    throws BeansException {

    if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
                if (ctors != null) {
                    return ctors;
                }
            }
        }
    }
    return null;
}

getEarlyBeanReference

获得提前暴露的bean引用。主要用于解决循环引用的问题。

重要实现类

AnnotationAwareAspectJAutoProxyCreator

@EnableAspectJAutoProxy会在spring容器中注册一个bean,AOP的实现,对符合条件的bean,自动生成代理对象。

Spring的Bean后置处理器之AnnotationAwareAspectJAutoProxyCreator

MergedBeanDefinitionPostProcessor

BeanPostProcessor的子接口,增加了postProcessMergedBeanDefinition方法。

用于处理合并后的BeanDefinition,在bean实例化后、属性赋值前回调。

void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

调用入口:

  • AbstractApplicationContext#refresh
  • AbstractApplicationContext#finishBeanFactoryInitialization(步骤11:实例化初始化所有非懒加载的单例bean)
  • DefaultListableBeanFactory#preInstantiateSingletons
  • AbstractBeanFactory#doGetBean
  • AbstractAutowireCapableBeanFactory#createBean
  • AbstractAutowireCapableBeanFactory#doCreateBean
  • AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof MergedBeanDefinitionPostProcessor) {
            MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
            bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
        }
    }
}

重要实现类

AutowiredAnnotationBeanPostProcessor

在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存,为后续属性赋值阶段的AutowiredAnnotationBeanPostProcessor处理做准备

CommonAnnotationBeanPostProcessor

在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存

DestructionAwareBeanPostProcessor

BeanPostProcessor的子接口,增加了postProcessBeforeDestruction,用于bean销毁前的回调。

重要实现类

CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法

 

posted @ 2023-12-19 11:49  残城碎梦  阅读(2229)  评论(0编辑  收藏  举报