spring 的后置处理器是 spring 生态得以繁荣的一个重要基础, 大量流行的框架都使用了各种类型的 PostProcessor 增强了自身的能力, 并为开发者提供了无数便利;
BeanDefinition 的后置处理
两种 BeanFactory 处理器对比
BeanDefinitionRegistryPostProcessor
和 BeanFactoryPostProcessor
是 Spring 框架中用于在容器启动过程中对 Bean 定义进行扩展和修改的两个重要接口, 它们的主要区别在于作用时机和功能范围;
BeanFactoryPostProcessor
BeanFactoryPostProcessor 是 Spring 提供的一个接口,允许在 Spring 容器实例化 Bean 之前对 BeanDefinition 进行修改; 它主要用于在容器加载 Bean 定义之后、实例化 Bean 之前,对 Bean 定义进行全局的修改或扩展;
使用场景:
- 修改 Bean 定义:例如,修改 Bean 的属性值、添加新的属性、修改 Bean 的作用域等。
- 动态注册 Bean:虽然 BeanFactoryPostProcessor 本身不能直接注册新的 Bean,但可以通过获取 BeanFactory 来间接实现。
- 配置文件的处理:例如,解析自定义的配置文件并将其转换为 Spring 的 Bean 定义。
举例如下:
1 | import org.springframework.beans.BeansException; |
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子接口,它在 BeanFactoryPostProcessor 的基础上提供了更早的扩展点。它允许在 Spring 容器加载 Bean 定义的过程中,直接操作 BeanDefinitionRegistry,从而可以动态注册、修改或删除 Bean 定义;
使用场景:
- 动态注册 Bean:在容器启动时,根据某些条件动态注册新的 Bean 定义。
- 修改或删除 Bean 定义:在 Bean 定义加载到容器之前,对已有的 Bean 定义进行修改或删除。
- 与 BeanFactoryPostProcessor 结合使用:在 BeanFactoryPostProcessor 之前执行,确保在 Bean 定义加载的早期阶段进行干预。
举例如下:
1 | import org.springframework.beans.BeansException; |
对比总结
特性 | BeanFactoryPostProcessor | BeanDefinitionRegistryPostProcessor |
---|---|---|
作用时机 | 在 Bean 定义加载之后、Bean 实例化之前 | 在 Bean 定义加载过程中,比 BeanFactoryPostProcessor 更早 |
功能范围 | 只能修改已有的 Bean 定义 | 可以动态注册、修改或删除 Bean 定义 |
继承关系 | 是 BeanDefinitionRegistryPostProcessor 的父接口 | 是 BeanFactoryPostProcessor 的子接口 |
使用场景 | 修改 Bean 定义、处理配置文件 | 动态注册 Bean、修改或删除 Bean 定义 |
使用建议:
- 如果你只需要修改已有的 Bean 定义,使用
BeanFactoryPostProcessor
即可。 - 如果你需要在 Bean 定义加载的过程中动态注册新的 Bean 或对 Bean 定义进行更早的干预,使用
BeanDefinitionRegistryPostProcessor
。
通过合理使用这两个接口,可以在 Spring 容器启动过程中对 Bean 定义进行灵活的扩展和定制;
加载与执行时机
PostProcessorRegistrationDelegate
1 | AbstractApplicationContext: |
先处理参数传进来的 beanFactoryPostProcessors:
1 | foreach processor in beanFactoryPostProcessors: |
然后处理已注册到 beanDefinitionRegistry 的 custom beanFactoryPostProcessors:
1 | // 从 registry 找出所有已注册的 beanFactoryPostProcessor 的 beanName |