在 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 {@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;}
}
🧱 三、执行顺序对比
阶段 | 执行内容 | 接口 |
---|
容器启动初期 | 加载 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 |