容器扩展点:BeanPostProcessor 与 Aware
引言
很多“魔法”(属性占位符解析、@Autowired 注入、AOP 代理生成)其实都是容器扩展点在工作。想在 Bean 创建过程中插手,Spring 给了两类钩子:针对 Bean 定义 的 BeanFactoryPostProcessor,和针对 Bean 实例 的 BeanPostProcessor;另有 Aware 系列让 Bean 反向感知容器能力。
核心概念
- BeanFactoryPostProcessor:容器读取完所有 Bean 定义后、实例化任何 Bean 之前执行,可修改/补充 BeanDefinition(改属性占位符、scope 等)。
PropertySourcesPlaceholderConfigurer就是典型实现。 - BeanDefinitionRegistryPostProcessor:BFPP 的子接口,额外允许注册新的 Bean 定义,执行时机更早。
- BeanPostProcessor:作用于每个 Bean 实例的初始化前后——
postProcessBeforeInitialization(在初始化回调前)与postProcessAfterInitialization(在初始化回调后)。AOP 自动代理创建器(AbstractAutoProxyCreator)、@Autowired处理器都是它。 - 多个处理器时用
Ordered/PriorityOrdered(或@Order)控制执行顺序。 - Aware 接口族:让 Bean 在初始化阶段拿到容器设施——
BeanNameAware、BeanFactoryAware、ApplicationContextAware(回调里拿 ApplicationContext)、EnvironmentAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware。
代码示例
// 1) BeanPostProcessor:观察每个 Bean 的初始化
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("before init: " + beanName);
return bean; // 必须原样返回(或返回包装后的代理)
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("after init: " + beanName);
return bean;
}
}
// 2) BeanFactoryPostProcessor:实例化前统一改默认 scope
@Component
public class ScopeFixer implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) {
// 把名称为 task 的 Bean 定义改成 prototype
BeanDefinition bd = factory.getBeanDefinition("task");
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
}
}
// 3) Aware:容器创建后把 ApplicationContext 交给需要它的 Bean
@Component
public class ContextUser implements ApplicationContextAware {
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext ctx) {
this.ctx = ctx; // 慎用:多数场景直接注入更优雅
}
}
注意点
- 在
@Configuration类里声明 BeanFactoryPostProcessor 相关的@Bean必须用 static 方法,否则会提前实例化配置类、破坏后处理器时序。 postProcessXxx的返回值会被当作最终 Bean:忘了return bean会注入 null;返回代理对象则替换原 Bean(AOP 正是这么干的)。- BeanPostProcessor 作用于容器里所有 Bean(包括它自己之外的每个),逻辑务必轻量、幂等。
- Aware 回调发生在依赖注入之后、初始化回调之前;能用构造器/
@Value表达就不要用 Aware,保持 Bean 对容器的无感知。 - 执行顺序:BeanDefinitionRegistryPostProcessor → BeanFactoryPostProcessor → 实例化 → BeanPostProcessor 生效。
小结
扩展点分两层:定义级(BeanFactoryPostProcessor 系,动手早、管 BeanDefinition)与实例级(BeanPostProcessor,围着每个 Bean 的初始化前后转),Aware 是 Bean 反向要资源的窗口。理解这三者,就能读懂 Spring 内部处理器,也能安全地写框架级扩展。