Aware 让 Bean 感知容器资源,BeanPostProcessor 让你全局干预 Bean 初始化;两者是 Spring 扩展与 AOP 实现的核心基石。
一、Aware 接口:让 Bean 感知容器
1. 核心作用
Aware 是 Spring 提供的标记接口(Marker Interface) ,自身无方法,用于让 Bean 在初始化阶段被动接收容器核心资源 (如 Bean 名称、上下文、环境、BeanFactory 等),实现 Bean 与容器的解耦通信。
- 解决问题:普通 Java 对象无法主动获取容器信息,Aware 通过容器回调注入资源,避免硬编码依赖容器 API。
- 本质:容器主动回调,而非 Bean 主动获取。
2. 常用 Aware 接口与回调
| Aware 接口 | 回调方法 | 注入资源 | 典型场景 |
|---|---|---|---|
BeanNameAware |
setBeanName(String) |
当前 Bean 在容器中的名称 | 日志、动态路由、注册 |
BeanFactoryAware |
setBeanFactory(BeanFactory) |
基础容器 BeanFactory | 手动获取/注册 Bean |
ApplicationContextAware |
setApplicationContext(ApplicationContext) |
应用上下文(高级容器) | 获取其他 Bean、国际化、事件发布 |
EnvironmentAware |
setEnvironment(Environment) |
环境配置(profile、配置项) | 读取配置、环境判断 |
ResourceLoaderAware |
setResourceLoader(ResourceLoader) |
资源加载器 | 加载文件、配置 |
MessageSourceAware |
setMessageSource(MessageSource) |
国际化消息源 | 多语言处理 |
3. 使用示例
java
@Component
public class MyAwareBean implements
BeanNameAware,
ApplicationContextAware,
EnvironmentAware {
private String beanName;
private ApplicationContext ctx;
private Environment env;
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("Bean 名称:" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ctx = applicationContext;
System.out.println("获取到 ApplicationContext");
}
@Override
public void setEnvironment(Environment environment) {
this.env = environment;
System.out.println("当前激活 profile:" + Arrays.toString(env.getActiveProfiles()));
}
// 业务方法:动态获取其他 Bean
public Object getOtherBean(String name) {
return ctx.getBean(name);
}
}
4. 底层原理(源码)
调用时机
在 AbstractAutowireCapableBeanFactory#initializeBean 中,实例化后、属性填充前执行:
java
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. 执行 Aware 回调(核心)
invokeAwareMethods(beanName, bean);
// 2. 执行 BeanPostProcessor#postProcessBeforeInitialization
applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 3. 执行初始化方法(@PostConstruct、afterPropertiesSet)
invokeInitMethods(beanName, wrappedBean, mbd);
// 4. 执行 BeanPostProcessor#postProcessAfterInitialization
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
// ...
}
核心方法:invokeAwareMethods
java
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// 1. BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// 2. BeanClassLoaderAware
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
// 3. BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
}
}
ApplicationContextAware 特殊处理
ApplicationContext 相关 Aware(如 ApplicationContextAware)不由 invokeAwareMethods 直接处理,而是通过 ApplicationContextAwareProcessor(一个 BeanPostProcessor) 在 postProcessBeforeInitialization 阶段回调:
java
// ApplicationContextAwareProcessor 源码
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
// 处理其他 ApplicationContext 相关 Aware
return bean;
}
5. 关键结论
- 调用顺序 :
BeanNameAware→BeanClassLoaderAware→BeanFactoryAware→(通过BeanPostProcessor)ApplicationContextAware。 - 执行时机 :实例化后、属性填充前、
BeanPostProcessor#before之前。 - 作用范围 :仅作用于实现了对应 Aware 接口的 Bean。
二、BeanPostProcessor:全局干预 Bean 初始化
1. 核心作用
BeanPostProcessor 是 Spring 提供的全局扩展接口 ,允许在每个 Bean 初始化的前后 插入自定义逻辑,可修改属性、替换对象、创建代理,是 Spring AOP、注解驱动、依赖注入的底层基石。
2. 接口定义(源码)
java
public interface BeanPostProcessor {
// 初始化方法(@PostConstruct、afterPropertiesSet)执行前调用
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 初始化方法执行后调用(AOP 代理创建点)
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
3. 执行时机(Bean 生命周期)
实例化(构造)
↓
填充属性(@Autowired、XML 注入)
↓
invokeAwareMethods(Aware 回调)
↓
postProcessBeforeInitialization(初始化前)
↓
执行初始化方法(@PostConstruct、afterPropertiesSet、init-method)
↓
postProcessAfterInitialization(初始化后 → AOP 代理)
↓
加入一级缓存,Bean 就绪
4. 使用示例:自定义后置处理器
场景 1:属性预处理(初始化前)
java
@Component
public class PropertyCheckProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 对所有 Bean 做属性校验/默认值填充
if (bean instanceof UserService) {
UserService userService = (UserService) bean;
if (userService.getTimeout() == null) {
userService.setTimeout(3000); // 设置默认值
}
}
return bean;
}
}
场景 2:AOP 代理/对象替换(初始化后)
java
@Component
public class LogProxyProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 为指定 Bean 创建日志代理
if (bean instanceof OrderService) {
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("方法执行前:" + method.getName());
Object result = method.invoke(bean, args);
System.out.println("方法执行后:" + method.getName());
return result;
}
);
}
return bean;
}
}
5. 底层原理(源码)
触发入口:applyBeanPostProcessorsBefore/AfterInitialization
java
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
// 遍历所有注册的 BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result; // 提前终止
}
result = current;
}
return result;
}
// postProcessAfterInitialization 逻辑完全一致
关键特性
- 全局生效 :默认对容器中所有 Bean 执行(可通过条件过滤)。
- 可替换对象:返回值可替换原始 Bean(AOP 代理核心)。
- 执行顺序 :可通过
@Order或实现Ordered接口控制。
6. Spring 内置核心 BeanPostProcessor
| 内置处理器 | 作用 |
|---|---|
ApplicationContextAwareProcessor |
处理 ApplicationContextAware 等回调 |
CommonAnnotationBeanPostProcessor |
处理 @PostConstruct、@PreDestroy、@Resource |
AutowiredAnnotationBeanPostProcessor |
处理 @Autowired、@Value、@Inject |
AnnotationAwareAspectJAutoProxyCreator |
AOP 代理创建(核心) |
三、Aware 与 BeanPostProcessor 对比与关联
1. 核心区别
| 维度 | Aware 接口 | BeanPostProcessor |
|---|---|---|
| 定位 | 让 Bean 感知容器 | 全局干预所有 Bean 初始化 |
| 作用对象 | 仅实现接口的 Bean | 容器中所有 Bean(默认) |
| 执行时机 | 实例化后、属性填充前 | 初始化前后(Aware 之后) |
| 能力 | 被动接收容器资源 | 主动修改/替换 Bean、创建代理 |
| 实现方式 | Bean 实现接口 | 独立类实现接口并注册为 Bean |
2. 关联关系
- Aware 依赖 BeanPostProcessor :
ApplicationContextAware等高级 Aware 由ApplicationContextAwareProcessor(BeanPostProcessor)触发。 - BeanPostProcessor 可使用 Aware :后置处理器自身可实现
BeanFactoryAware等,获取容器资源。 - AOP 实现 :
AnnotationAwareAspectJAutoProxyCreator(BeanPostProcessor)在postProcessAfterInitialization阶段创建 AOP 代理。
四、总结
- Aware :感知型回调,让 Bean 获取容器资源,解耦 Bean 与容器 API,执行于初始化早期。
- BeanPostProcessor :全局拦截器,在初始化前后干预所有 Bean,支持属性修改、对象替换、AOP 代理,是 Spring 扩展的核心。
- 协作关系:Aware 提供容器感知能力,BeanPostProcessor 提供全局定制能力,共同构成 Spring IoC 容器的扩展体系。
- 核心应用 :
@Autowired、@PostConstruct、AOP、事务管理均基于这两个机制实现。