Spring Bean 生命周期深度解析:从初始化到销毁的完整流程
Spring Bean 的生命周期是 Spring 容器管理 Bean 的核心逻辑,涵盖 “Bean 定义加载→实例化→属性注入→初始化→使用→销毁” 全流程。每个阶段都允许开发者通过接口或注解插入自定义逻辑,而 后置处理器(BeanPostProcessor/BeanFactoryPostProcessor) 则是扩展生命周期的关键机制。从 “生命周期完整流程→核心阶段解析→后置处理器详解→实战验证” 四个维度,彻底拆解 Spring Bean 的生命周期。
Spring Bean 生命周期全景图(核心流程)
Spring Bean 的生命周期可分为 “容器初始化阶段” 和 “容器销毁阶段”,每个阶段包含多个关键节点,严格遵循固定顺序:
容器初始化阶段:Bean 的创建与初始化
容器初始化阶段是 Bean 从 “定义” 到 “就绪” 的核心过程,每个节点都有明确的职责和触发时机。逐阶段解析:
1. 阶段 1:BeanFactoryPostProcessor 调用(容器级后置处理)
- 触发时机:Spring 容器加载完所有
BeanDefinition(Bean 的元数据)后,Bean 实例化前(此时仅解析配置,未创建任何 Bean 实例)。 - 核心作用:修改
BeanDefinition的配置(如动态修改属性值、添加依赖),扩展容器功能。 - 实现方式:实现
BeanFactoryPostProcessor接口,重写postProcessBeanFactory方法。
代码对应与输出
1 | // 容器后置处理器实现 |
输出结果:BeanFactoryPostProcessor#postProcessBeanFactory
关键说明:此时 Person 的 BeanDefinition 已加载,但 Person 实例尚未创建。
2. 阶段 2:Bean 实例化(构造器调用)
- 触发时机:
BeanDefinition处理完成后,容器首次需要该 Bean 时(ApplicationContext 会立即实例化单例 Bean,BeanFactory 延迟实例化)。 - 核心作用:通过反射调用 Bean 的构造器,创建 Bean 实例(内存中分配对象)。
- 注意事项:默认调用 无参构造器(若使用构造器注入,调用对应有参构造器)。
代码对应与输出
1 | // Person 类的无参构造器 |
输出结果:构造器
关键说明:此时 Bean 已实例化,但属性(如 name)尚未赋值。
3. 阶段 3:属性注入(setter 方法调用)
- 触发时机:Bean 实例化后,容器根据
BeanDefinition中的属性配置(如 XML 的<property>或注解@Autowired),调用 Bean 的setter方法注入属性。 - 核心作用:为 Bean 填充依赖(简单类型或其他 Bean 引用)。
代码对应与输出
1 | // Person 类的 setName 方法 |
输出结果:set属性
关键说明:此时 Bean 的属性已赋值(如 name 被设为配置中的值)。
4. 阶段 4:Aware 接口回调(Bean 感知容器信息)
- 触发时机:属性注入完成后,初始化方法执行前。
- 核心作用:让 Bean 感知 Spring 容器的信息(如自身 Bean 名称、容器实例),实现特定接口即可接收回调。
- 常用 Aware 接口(执行顺序固定):
| 接口 | 回调方法 | 核心作用 |
|---|---|---|
BeanNameAware |
setBeanName(String beanName) |
注入当前 Bean 在容器中的 id 或 name |
BeanFactoryAware |
setBeanFactory(BeanFactory bf) |
注入当前 Bean 所属的 BeanFactory 实例 |
ApplicationContextAware |
setApplicationContext(ApplicationContext ac) |
注入当前 Bean 所属的 ApplicationContext 实例(仅在 ApplicationContext 容器中生效) |
代码对应与输出
1 | // BeanNameAware 实现 |
输出结果:
1 | BeanNameAware#setBeanName |
关键说明:ApplicationContextAware 仅在 ApplicationContext 容器中生效(如 ClassPathXmlApplicationContext),BeanFactory 容器不支持该接口。
5. 阶段 5:BeanPostProcessor 前置处理(增强 Bean 初始化前)
- 触发时机:Aware 接口回调完成后,初始化方法执行前。
- 核心作用:对 Bean 实例进行前置增强(如修改属性值、添加日志、生成代理的准备工作)。
- 实现方式:实现
BeanPostProcessor接口,重写postProcessBeforeInitialization方法,必须返回 Bean 实例(否则后续无法获取该 Bean)。
代码对应与输出
1 | // Bean 后置处理器实现 |
输出结果:BeanPostProcessor#postProcessBeforeInitialization
关键说明:若返回 null,容器会认为该 Bean 已被处理且无需后续步骤,后续 getBean() 会返回 null。
6. 阶段 6:初始化回调(Bean 自定义初始化逻辑)
- 触发时机:BeanPostProcessor 前置处理完成后,Bean 正式就绪前。
- 核心作用:执行 Bean 的自定义初始化逻辑(如初始化资源、连接数据库)。
- 四种实现方式(执行顺序固定,优先级从高到低):
| 实现方式 | 核心代码示例 | 执行时机优先级 |
|---|---|---|
1. @PostConstruct 注解 |
@PostConstruct public void postConstruct() {} |
最高(最先执行) |
2. InitializingBean 接口 |
@Override public void afterPropertiesSet() {} |
次之 |
3. 自定义 init-method |
XML 配置:<bean init-method="myInit"/> |
最低(最后执行) |
4. @Bean(initMethod) |
Java 配置:@Bean(initMethod = "myInit") |
与 3 同级(XML 和 Java 配置的区别) |
代码对应与输出
1 | // 1. @PostConstruct 注解方法 |
输出结果:
1 | @PostConstruct注解 |
关键说明:若多种方式并存,会按上述顺序执行;初始化方法抛出异常会导致 Bean 初始化失败,容器启动报错。
7. 阶段 7:BeanPostProcessor 后置处理(增强 Bean 初始化后)
- 触发时机:初始化回调完成后,Bean 就绪前。
- 核心作用:对 Bean 实例进行后置增强(如生成 AOP 代理、最终属性修改),是 Spring AOP 实现的核心节点。
- 实现方式:实现
BeanPostProcessor接口,重写postProcessAfterInitialization方法,必须返回 Bean 实例。
代码对应与输出
1 | // Bean 后置处理器实现(续) |
输出结果:BeanPostProcessor#postProcessAfterInitialization
关键场景:Spring AOP 的 AnnotationAwareAspectJAutoProxyCreator(内置 BeanPostProcessor)会在此阶段为 Bean 生成代理对象。
8. 阶段 8:Bean 就绪(可使用)
- 触发时机:BeanPostProcessor 后置处理完成后。
- 核心状态:Bean 已完全初始化,属性、依赖、增强逻辑均已生效,可通过
ApplicationContext.getBean()获取并使用。
代码对应与输出
1 | // 容器初始化完成,获取 Bean 并使用 |
输出结果:---容器初始化成功
容器销毁阶段:Bean 的资源释放
当容器关闭时(如 applicationContext.close()),Spring 会触发 Bean 的销毁流程,执行自定义销毁逻辑,释放资源(如关闭数据库连接、释放文件句柄)。
1. 触发时机
ApplicationContext容器:调用close()方法时主动触发;BeanFactory容器:默认不主动销毁 Bean,需手动调用destroySingletons()。
2. 三种销毁回调方式(执行顺序固定,优先级从高到低)
| 实现方式 | 核心代码示例 | 执行时机优先级 |
|---|---|---|
1. @PreDestroy 注解 |
@PreDestroy public void myPreDestroy() {} |
最高(最先执行) |
2. DisposableBean 接口 |
@Override public void destroy() {} |
次之 |
3. 自定义 destroy-method |
XML 配置:<bean destroy-method="myDestory"/> |
最低(最后执行) |
代码对应与输出
1 | // 1. @PreDestroy 注解方法 |
输出结果:
1 | @PreDestroy |
关键说明:仅 单例 Bean 会触发销毁流程(容器关闭时),原型 Bean 由开发者手动管理销毁(容器不跟踪原型 Bean 的生命周期)。
后置处理器详解:BeanPostProcessor vs BeanFactoryPostProcessor
后置处理器是 Spring 扩展容器和 Bean 的核心机制,分为 Bean 后置处理器(增强 Bean)和 容器后置处理器(增强容器),二者在作用对象、触发时机上有本质区别。
1. Bean 后置处理器(BeanPostProcessor)
核心定位
- 作用对象:容器中的 Bean 实例(对每个 Bean 实例生效,可按 BeanName 过滤);
- 触发时机:Bean 实例化后、初始化前后;
- 核心能力:修改 Bean 实例属性、生成代理、添加日志等(Spring AOP 依赖此机制);
- 关键注意事项:
- 必须返回 Bean 实例(返回
null会导致后续无法获取该 Bean); ApplicationContext会 自动扫描并注册 所有BeanPostProcessor类型的 Bean;BeanFactory需 手动注册(需调用beanFactory.addBeanPostProcessor(bp))。
- 必须返回 Bean 实例(返回
手动注册示例(BeanFactory 容器)
1 | // 1. 创建 BeanFactory 容器 |
2. 容器后置处理器(BeanFactoryPostProcessor)
核心定位
- 作用对象:Spring 容器本身(
ConfigurableListableBeanFactory); - 触发时机:所有
BeanDefinition加载完成后、Bean 实例化前; - 核心能力:修改
BeanDefinition配置(如动态修改属性值、添加依赖、删除 Bean 定义); - 关键注意事项:
- 仅作用于
BeanDefinition(元数据),不涉及 Bean 实例; ApplicationContext会 自动扫描并注册 所有BeanFactoryPostProcessor类型的 Bean;- 常用实现类:
PropertyPlaceholderConfigurer(处理${}占位符)、CustomAutowireConfigurer(自定义自动装配规则)。
- 仅作用于
实战示例:动态修改 BeanDefinition
1 |
|
效果:容器实例化 person Bean 时,name 属性会被设为 “李四”,且会先实例化 otherBean。
3. 二者核心区别对比
| 对比维度 | BeanPostProcessor(Bean 后置处理器) | BeanFactoryPostProcessor(容器后置处理器) |
|---|---|---|
| 作用对象 | Bean 实例 | 容器(BeanDefinition) |
| 触发时机 | Bean 实例化后、初始化前后 | BeanDefinition 加载完成后、Bean 实例化前 |
| 核心操作 | 修改 Bean 实例、生成代理 | 修改 BeanDefinition(元数据) |
| 注册方式(ApplicationContext) | 自动注册 | 自动注册 |
| 注册方式(BeanFactory) | 手动注册(addBeanPostProcessor) | 手动注册(addBeanFactoryPostProcessor) |
| 典型应用 | Spring AOP 代理生成、Bean 增强 | 处理 ${} 占位符、动态修改配置 |
实战验证:生命周期输出与代码对应
完整对应生命周期的每个阶段:
1 | public class Main { |
输出结果(按执行顺序)
1 | 1. BeanFactoryPostProcessor#postProcessBeanFactory // 容器后置处理 |
关键结论
- 顺序不可变:Spring 严格按上述顺序执行生命周期,任何阶段的异常都会导致容器初始化或 Bean 创建失败;
- 单例 vs 原型:单例 Bean 生命周期与容器一致(容器初始化时创建,关闭时销毁);原型 Bean 每次
getBean()都会重新执行 “实例化→属性注入→初始化”,容器不管理其销毁; - 扩展灵活:通过后置处理器和生命周期回调,可在不修改 Bean 核心逻辑的前提下,灵活扩展功能(如日志、监控、AOP)。
总结:Bean 生命周期的核心价值
Spring Bean 生命周期的核心价值在于 “可控性” 和 “扩展性”:
- 可控性:开发者可在 Bean 生命周期的任意阶段插入自定义逻辑(如初始化前检查配置、销毁前释放资源);
- 扩展性:后置处理器允许在不修改 Bean 代码的情况下,对 Bean 或容器进行增强(如 Spring AOP、动态配置);
- 标准化:统一的生命周期流程确保所有 Bean 遵循相同的初始化和销毁规则,降低团队协作成本
v1.3.10