当前位置: 首页 > java >正文

BeanFactoryPostProcessor 与 BeanPostProcessor 的区别

在 Spring 框架中,BeanFactoryPostProcessorBeanPostProcessor 是两个核心的扩展接口,它们都用于对 Spring 容器进行自定义处理,但它们的作用时机处理对象使用场景 有显著区别。


🧠 一、核心区别对比表

特性BeanFactoryPostProcessorBeanPostProcessor
处理对象BeanDefinition(Bean 的元信息)Bean 实例
作用时机容器加载完所有 BeanDefinition 后,但尚未实例化任何 Bean 时每个 Bean 实例化之后、初始化之前/之后
处理内容修改 Bean 的定义信息(如类名、属性、作用域等)修改 Bean 实例的行为(如 AOP 代理、字段注入)
是否影响容器结构✅ 是,可以新增、修改、删除 BeanDefinition❌ 否,只影响 Bean 实例
是否支持多个实现✅ 支持多个实现类,可通过 @Order 控制执行顺序✅ 支持多个实现类,可通过 @Order 控制执行顺序
是否可访问容器✅ 可以访问 ConfigurableListableBeanFactory✅ 可以访问容器中的 Bean 实例

🔄 二、详细说明

✅ 1. BeanFactoryPostProcessor

📌 作用:
  • 在 Spring 容器加载完所有 BeanDefinition(即 XML 或注解配置的 Bean 元信息)之后,但在任何 Bean 实例化之前执行。
  • 允许你修改或新增 BeanDefinition,比如:
    • 修改某个 Bean 的类名
    • 修改某个 Bean 的作用域(如 singleton、prototype)
    • 添加新的 BeanDefinition
📁 核心方法:
public interface BeanFactoryPostProcessor {void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
🧩 典型应用场景:
  • PropertyPlaceholderConfigurer:替换配置文件中的占位符(如 ${jdbc.url}
  • MapperScannerConfigurer:扫描 MyBatis 的 Mapper 接口,生成对应的 BeanDefinition
  • 动态注册新 BeanDefinition(如根据配置动态添加 Bean)
🧱 示例:
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {if (beanFactory.containsBeanDefinition("myBean")) {BeanDefinition bd = beanFactory.getBeanDefinition("myBean");bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);}}
}

✅ 2. BeanPostProcessor

📌 作用:
  • 在每个 Bean 实例化之后、初始化之前/之后执行。
  • 允许你对 Bean 实例进行增强(如 AOP 代理、字段注入、日志增强等)。
  • 不影响容器结构,只影响 Bean 实例。
📁 核心方法:
public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
🧩 典型应用场景:
  • AutowiredAnnotationBeanPostProcessor:处理 @Autowired@Value 注解
  • CommonAnnotationBeanPostProcessor:处理 @Resource@PostConstruct@PreDestroy
  • AbstractAutoProxyCreator:AOP 代理生成(如 @Aspect 切面织入)
  • 日志增强、性能监控、安全控制等
🧱 示例:
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof MyService) {return ProxyFactory.getProxy(bean);}return bean;}
}

🧱 三、执行顺序对比

阶段执行内容接口
容器启动初期加载 BeanDefinitionBeanDefinitionRegistryPostProcessor(早于 BeanFactoryPostProcessor
容器结构准备阶段修改 BeanDefinitionBeanFactoryPostProcessor
Bean 实例化阶段实例化 BeanInstantiationAwareBeanPostProcessor(可拦截实例化前/后)
Bean 初始化阶段初始化前调用BeanPostProcessor.postProcessBeforeInitialization()
Bean 初始化完成阶段初始化后调用BeanPostProcessor.postProcessAfterInitialization()

🧩 四、常见使用场景对比

场景推荐接口
替换配置文件中的占位符(如 ${}BeanFactoryPostProcessor
扫描 MyBatis Mapper 接口BeanFactoryPostProcessor
注册新的 BeanDefinitionBeanFactoryPostProcessor
AOP 代理织入(如 @AspectBeanPostProcessor
@Autowired@Resource 注入BeanPostProcessor
@PostConstruct@PreDestroy 处理BeanPostProcessor
日志记录、性能监控、安全控制BeanPostProcessor

❗ 五、注意事项

事项说明
BeanFactoryPostProcessor 无法访问 Bean 实例因为它在 Bean 实例化之前执行
BeanPostProcessor 不能影响容器结构它只能修改 Bean 实例,不能新增或删除 BeanDefinition
两者都可以有多个实现可通过 @Order 或实现 Ordered 接口控制执行顺序
BeanFactoryPostProcessor 通常用于配置处理如替换占位符、动态注册 Bean
BeanPostProcessor 通常用于行为增强如 AOP、字段注入、日志增强等

✅ 六、总结

特性BeanFactoryPostProcessorBeanPostProcessor
作用时机容器加载完 BeanDefinitionBean 实例化后、初始化前后
处理对象BeanDefinitionBean 实例
是否影响容器结构✅ 是❌ 否
是否可访问容器✅ 是✅ 是
典型用途修改配置、注册新 BeanAOP 代理、字段注入、日志增强
执行顺序早于 BeanPostProcessor晚于 BeanFactoryPostProcessor

http://www.xdnf.cn/news/4438.html

相关文章:

  • 【Qt】Qt 构建系统详解:qmake 入门到项目实战
  • 鸿蒙开发——2.ArkTS声明式开发(页面和自定义组件)
  • HTTP请求与缓存、页面渲染全流程
  • 【Java ee 初阶】多线程(8)
  • Redis再次开源!reids8.0.0一键安装脚本分享
  • CentOS算法部署
  • ROS2: 服务通信
  • 机器学习实操 第二部分 神经网路和深度学习 第14章 使用卷积神经网络进行深度计算机视觉
  • 精益数据分析(48/126):UGC商业模式的指标剖析与运营策略
  • 8. HTML 表单基础
  • PostgreSQL给新用户授权select角色
  • 【C++】类和对象(下)
  • day009-用户管理专题
  • 304.不同的二叉搜索树
  • mysql:什么是一致性视图(Read View)
  • AI应用开发实战分享
  • C++模板
  • Python引领前后端创新变革,重塑数字世界架构
  • ✍️【TS类型体操进阶】挑战类型极限,成为类型魔法师![特殊字符]♂️✨
  • iTwin 数据报表(只是简单的原型不代表实现)
  • python 使用 mongodb 的一些方法
  • Spring Boot 中如何解决 CORS 问题(详解)
  • 【Java ee 初阶】多线程(9)上
  • Redis从入门到实战 - 高级篇(上)
  • day 14 SHAP可视化
  • Android学习总结之Binder篇
  • 空间数据分析新趋势:AI 与 ArcGIS Pro 的协同创新
  • 从零开始学习three.js(15):一文详解three.js中的纹理映射UV
  • 经典密码学算法实现
  • Apache Calcite 详细介绍