深入理解 Spring Bean 后处理器:@Autowired 等注解的本质
在日常开发中,我们几乎每天都会用到 @Autowired
、@Value
、@Resource
、@PostConstruct
等注解。
但你是否想过,这些“神奇”的注入和生命周期回调机制,是谁在幕后完成的?
今天我们通过一个非常简洁的 Demo,一步步揭开 Spring Bean 后处理器的秘密。
一、代码示例
package com.itheima.a04;import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;/** Bean 后处理器的作用演示*/
public class A04 {public static void main(String[] args) {// 1️⃣ 创建一个“干净”的容器(没有任何自动注册的组件)GenericApplicationContext context = new GenericApplicationContext();// 2️⃣ 手动注册一些普通 Beancontext.registerBean("bean1", Bean1.class);context.registerBean("bean2", Bean2.class);context.registerBean("bean3", Bean3.class);context.registerBean("bean4", Bean4.class);// 3️⃣ 配置容器的自动注入解析策略(支持 @Value)context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());// 4️⃣ 手动注册各种 Bean 后处理器context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 负责解析 @Autowired 和 @Valuecontext.registerBean(CommonAnnotationBeanPostProcessor.class); // 负责解析 @Resource、@PostConstruct、@PreDestroyConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory()); // 负责解析 @ConfigurationProperties// 5️⃣ 初始化容器(执行 BeanFactory 后处理器、添加 BeanPostProcessor、初始化所有单例 Bean)context.refresh();System.out.println(context.getBean(Bean1.class));// 6️⃣ 关闭容器,触发销毁回调context.close();/*学到什么?✅ 1. @Autowired、@Value、@Resource、@PostConstruct 等注解的功能,都是由 Bean 后处理器在 Bean 生命周期阶段完成的。✅ 2. Bean 后处理器本身也是一种“插件机制”,可以扩展 Spring 的核心行为。*/}
}
二、Demo 核心逻辑解析
这段代码其实干了三件事:
1️⃣ 创建一个干净的容器
GenericApplicationContext
是 Spring 提供的一个空白容器实现。
它不像 AnnotationConfigApplicationContext
那样自动注册注解处理器、扫描包路径或加载配置类。
换句话说,它是“白纸一张”,这就让我们可以手动控制 Spring 容器内部机制。
GenericApplicationContext context = new GenericApplicationContext();
2️⃣ 手动注册 Bean 与处理器
正常情况下,Spring 会自动帮你注册 AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
等组件。
但这里我们手动注册它们,以便更清楚地看到它们的作用:
注册组件 | 功能说明 |
---|---|
AutowiredAnnotationBeanPostProcessor | 解析 @Autowired 、@Value |
CommonAnnotationBeanPostProcessor | 解析 @Resource 、@PostConstruct 、@PreDestroy |
ConfigurationPropertiesBindingPostProcessor | 解析 @ConfigurationProperties |
ContextAnnotationAutowireCandidateResolver | 支持 @Value("${}") 等表达式解析 |
这几行代码告诉我们:
👉 Spring 并没有“魔法”地识别这些注解,而是通过后处理器扩展点去实现的。
3️⃣ 初始化容器与销毁
context.refresh()
会触发以下流程:
- 执行
BeanFactoryPostProcessor
(工厂级别的增强) - 注册所有
BeanPostProcessor
- 实例化所有单例 Bean
- 在创建 Bean 的过程中,各个后处理器开始发挥作用,完成依赖注入与生命周期方法调用。
随后,context.close()
会触发销毁阶段,执行:
@PreDestroy
注解的方法DisposableBean
接口方法- 自定义销毁回调
三、结论:后处理器是 Spring 的灵魂
这个 Demo 的意义非常深刻,它揭示了一个关键真相:
Spring 框架中几乎所有“魔法”都是通过 Bean 后处理器(BeanPostProcessor)实现的。
下面是一个简单的关系图,帮助理解:
Spring Bean 生命周期(精简版)实例化前 → [InstantiationAwareBeanPostProcessor]构造方法执行(实例化)属性注入 → [AutowiredAnnotationBeanPostProcessor]初始化前 → [CommonAnnotationBeanPostProcessor 处理 @PostConstruct]初始化后 → [AOP、代理增强等]销毁前 → [CommonAnnotationBeanPostProcessor 处理 @PreDestroy]
四、总结
关键点 | 说明 |
---|---|
后处理器是 Spring 可扩展机制的核心 | 所有注解的功能其实都是“插件化”的 |
@Autowired 等注解不是语法糖,而是由后处理器解释执行的 | 运行期反射完成依赖注入 |
容器生命周期由 refresh() 驱动 | 包括 Bean 定义加载、处理器注册、Bean 实例化、初始化等步骤 |
你也可以编写自己的 BeanPostProcessor | 比如自定义注解、监控 Bean 加载时间、实现 AOP 增强等 |
五、总结一句话
Spring 的强大,不在于注解本身,而在于它提供了可以“挂接任意逻辑”的生命周期扩展机制。