BeanPostProcessor和BeanFactoryPostProcessor族类原理及使用
来源:     阅读:2
易浩激活码
发布于 2025-10-27 22:52
查看主页

1. 作用及区别

从 Spring+IOC容器源码分析 一文中的分析中,贯穿整个过程主线的大致是这样一条路线:

当然这其中还有相当多的实现细节,包括 容器加载前的准备、Bean容器的准备等等。

这篇文章要说的是Spring框架中两个相当重大的类族:BeanFactoryPostProcessorBeanPostProcessor

其应用的位置对应于上面的过程2和4,也就是:

注意要区分这两个类的作用以及调用时间和作用对象都是不同的

2. 常见的实现类解析

下面这些实现类都是在分析SpringIOC源码时提到过的,在这里我们再详细的看一下他们的作用以及调用事件

本文中提到的所有这些实现类都是在SpringIOC源码分析中提到过的,其在源码中具体的使用位置可以查看 SpringIOC源码分析 等三篇文章

2.1 BeanFactoryPostProcessor 的常见实现类

2.1.2 BeanDefinitionRegistryPostProcessor:

  1. 官方注解:对标准 BeanFactoryPostProcessor SPI的扩展,允许在常规BeanFactoryPostProcessor检测启动之前注册进一步的bean定义。特别地,BeanDefinitionRegistryPostProcessor可以注册更多的bean定义,这些定义反过来定义BeanFactoryPostProcessor实例

也就是说第一作为一个 BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor 也可以对应用程序上下文的内部Bean工厂进行其初始化后的修改,也就是可以允许修改Bean定义,例如重写或者添加Bean属性
另外的,作为 BeanDefinitionRegistryPostProcessor 自身这样一个特殊的 BeanFactoryPostProcessor来讲,其接口中的方法允许自定义的去添加更多的Bean定义,例如在这里去添加更多的 BeanFactoryPostProcessor 实例

总结一下:BeanFactoryPostProcessor可以修改各个注册的Bean,BeanDefinitionRegistryPostProcessor则可以动态的注册Bean到容器中

  1. 使用:BeanDefinitionRegistryPostProcessor 在Spring源码中的使用主要是在这块:invokeBeanFactoryPostProcessors(),具体的调用过程分析可以查看 Spring+IOC容器源码分析 文中关于 invokeBeanFactoryPostProcessors的总结

2.1.1 ConfigurationClassPostProcessor

  1. ConfigurationClassPostProcessor 是 BeanDefinitionRegistryPostProcessor 的实现类,是用于对Configuration类的引导处理的BeanFactoryPostProcessor的扩展

在当下基于springBoot注解开发应用已经相当广泛的情况下,可以说这个后置处理器是整个 spring中最最核心的处理器也不为过。
不同于xml方式通过解析xml文件获取到所有Bean定义并将其注册到相应的缓存,基于注解配置后将所有Bean配置解析成BeanDefinition都是由这个处理器来完成的。例如我们常见的:@controller,@service,@mapper,@component,@configuration以及@Import等等

2.调用时机以及作用:

第一 ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessorPriorityOrdered接口,那么从我们在之前的文章对BeanFactoryPostProcess调用的方法 invokeBeanFactoryPostProcessors()的分析中:
ConfigurationClassPostProcessor 也是在这里进行调用的.通过实则现类,主要是调用实则现的两个方法:

2.2 BeanPostProcessor的常见实现类

2.2.1 ApplicationContextAwareProcessor

顾名思义,ApplicationContextAwareProcessorBeanPostProcessor对应用上下文中的aware类的处理器扩展

第一了解下Spring中的aware类,aware意为"可感知的",在spring中主要是用来提供对某种容器级的Bean的便捷的获取和连接方式
例如:一般在我们的项目里边会有一个用来直接获取Bean的工具类,那么在这里就必须要拿到当前存放Bean的BeanFactory,有许多方式获取到.

  1. 实现BeanFactoryAware接口,调用setBeanFactory(BeanFactory beanFactory)将beanFactory赋值给本地beanFactory即可

  2. 实现ApplicationContextAware接口,调用setApplicationContext(ApplicationContext applicationContext)从applicationContext中获取到beanFactory赋值给本地beanFactory

  3. 实现BeanFactoryPostProcessor,拿到BeanFactory.(这里用BeanFactoryPostProcessor有点杀鸡用牛刀的感觉,本来是用来做BeanDefinition修改的,这里只是使用了其容器的引用)

  4. 直接注入BeanFactory,再使用自定义的初始化将其赋值到本地

从IOC源码分析中,我们知道实则最终创建的BeanFactory是一个DefaultListableBeanFactory,因此在1、2中的BeanFactory可以直接强转为DefaultListableBeanFactory,以此可以调用更多详细的获取Bean的方法

扯远了,想一个问题,无论是我们从aware接口获取值,还是直接注入值,这些aware接口是什么时候拿到这些引用的呢?这也就是这个processor的作用

在Spring+IOC容器源码分析 一文中准备Bean容器的部分:
prepareBeanFactory(factory)中看到了在这里创建了一个ApplicationContextAwareProcessor并传入了当前上下文引用作为其构造参数
查看源码我们发现:

2.2.2 InstantiationAwareBeanPostProcessor 实例化可感知的BeanPostProcessor

该类相比较与父接口自定义了三个方法,这三个方法都是与bean的实例化相关的,这也印证了该类型名称:InstantiationAware

  1. 主要作用:对目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

  2. InstantiationAwareBeanPostProcessor 接口方法的执行顺序:

1. createBean--resolveBeforeInstantiation--applyBeanPostProcessorsBeforeInstantiation
2. populateBean

2.2.3 SmartInstantiationAwareBeanPostProcessor    循环引用获取早期引用

  1. InstantiationAwareBeanPostProcessor接口的扩展,添加了一个用于预测已处理bean的最终类型的回调.

  2. 方法分析:

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

    选择合适的构造器,列如目标对象有多个构造器,在这里可以进行一些定制化,选择合适的构造器.beanClass参数表明目标实例的类型,beanName是目标实例在Spring容器中的name
    返回值是个构造器数组,如果返回null,会执行下一个PostProcessor的determineCandidateConstructors方法;否则选取该PostProcessor选择的构造器
    具体的使用:如AutowiredAnnotationBeanPostProcessor实现将自动扫描通过@Autowired/@Value注解的构造器从而可以完成构造器注入

    获得提前暴露的bean引用。主要用于解决循环引用的问题;只有单例对象才会调用此方法

    • Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;

    • Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;

    • Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException;

2.2.4 MergedBeanDefinitionPostProcessor:合并Bean定义的PostProcessor

  1. 运行时对合并的bean定义的后处理器回调接口。BeanPostProcessor的子接口实现,以便对Spring BeanFactory用于创建bean实例的合并bean定义(原始bean定义的已处理副本)进行后处理。

例如,{@link#postprocessemergedbeandefinition}方法可以内省bean定义,以便在对bean的实际实例进行后处理之前准备一些缓存的元数据。它还允许修改bean定义,但仅限于实际用于并发修改的定义属性。本质上,这只适用于在{@link RootBeanDefinition}本身上定义的操作,而不适用于其基类的属性

  1. 使用的位置:doCreateBean()

2.2.5 AutowiredAnnotationBeanPostProcessor

BeanPostProcessor的实现,自动连接带注释的字段、setter方法和任意配置方法。要注入的这些成员是通过注释检测到的:默认情况下,处理Spring的@Autowired和@Value注释
简单来说就是与Spring的autoWired自动注入相关的一个BeanPostProcessor,我们之所以能方便的使用@Autowired注入其他Bean都要归功于这个注解

关于该类详细的解析将在自动注入原理与AutowiredAnnotationBeanPostProcessor 一文中

2.2.7 DestructionAwareBeanPostProcessor

BeanPostProcessor的子接口,用于添加销毁前回调。典型用法是对特定bean类型调用定制的销毁回调,匹配相应的初始化回调

免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境
相关推荐
iOS 封装runtime库,一句话可实现方法交换
Gradle更小、更快构建APP的奇淫技巧
在Windows中通过SSH工具连接虚拟机中的Linux
HignCharts:线形图饼图绘制及时间等定制
不用解锁!红米3最完美ROOT方法出炉
首页
搜索
订单
购物车
我的