在 Spring 框架中,BeanFactoryPostProcessor 和 BeanPostProcessor 是两个核心的扩展接口,它们都用于对 Spring 容器进行自定义处理,但它们的作用时机、处理对象 和 使用场景 有显著区别。
🧠 一、核心区别对比表
| 特性 | BeanFactoryPostProcessor | BeanPostProcessor |
|---|
| 处理对象 | 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 {
@Override
public 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 {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
🧩 典型应用场景:
AutowiredAnnotationBeanPostProcessor:处理 @Autowired、@Value 注解CommonAnnotationBeanPostProcessor:处理 @Resource、@PostConstruct、@PreDestroyAbstractAutoProxyCreator:AOP 代理生成(如 @Aspect 切面织入)- 日志增强、性能监控、安全控制等
🧱 示例:
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyService) {
return ProxyFactory.getProxy(bean);
}
return bean;
}
}
🧱 三、执行顺序对比
| 阶段 | 执行内容 | 接口 |
|---|
| 容器启动初期 | 加载 BeanDefinition | BeanDefinitionRegistryPostProcessor(早于 BeanFactoryPostProcessor) |
| 容器结构准备阶段 | 修改 BeanDefinition | BeanFactoryPostProcessor |
| Bean 实例化阶段 | 实例化 Bean | InstantiationAwareBeanPostProcessor(可拦截实例化前/后) |
| Bean 初始化阶段 | 初始化前调用 | BeanPostProcessor.postProcessBeforeInitialization() |
| Bean 初始化完成阶段 | 初始化后调用 | BeanPostProcessor.postProcessAfterInitialization() |
🧩 四、常见使用场景对比
| 场景 | 推荐接口 |
|---|
替换配置文件中的占位符(如 ${}) | BeanFactoryPostProcessor |
| 扫描 MyBatis Mapper 接口 | BeanFactoryPostProcessor |
| 注册新的 BeanDefinition | BeanFactoryPostProcessor |
AOP 代理织入(如 @Aspect) | BeanPostProcessor |
@Autowired、@Resource 注入 | BeanPostProcessor |
@PostConstruct、@PreDestroy 处理 | BeanPostProcessor |
| 日志记录、性能监控、安全控制 | BeanPostProcessor |
❗ 五、注意事项
| 事项 | 说明 |
|---|
BeanFactoryPostProcessor 无法访问 Bean 实例 | 因为它在 Bean 实例化之前执行 |
BeanPostProcessor 不能影响容器结构 | 它只能修改 Bean 实例,不能新增或删除 BeanDefinition |
| 两者都可以有多个实现 | 可通过 @Order 或实现 Ordered 接口控制执行顺序 |
BeanFactoryPostProcessor 通常用于配置处理 | 如替换占位符、动态注册 Bean |
BeanPostProcessor 通常用于行为增强 | 如 AOP、字段注入、日志增强等 |
✅ 六、总结
| 特性 | BeanFactoryPostProcessor | BeanPostProcessor |
|---|
| 作用时机 | 容器加载完 BeanDefinition 后 | Bean 实例化后、初始化前后 |
| 处理对象 | BeanDefinition | Bean 实例 |
| 是否影响容器结构 | ✅ 是 | ❌ 否 |
| 是否可访问容器 | ✅ 是 | ✅ 是 |
| 典型用途 | 修改配置、注册新 Bean | AOP 代理、字段注入、日志增强 |
| 执行顺序 | 早于 BeanPostProcessor | 晚于 BeanFactoryPostProcessor |