Spring Bean 的生命周期是 从 Bean 实例创建到最终销毁的完整过程,核心围绕 “容器管理 Bean 的初始化、依赖注入、使用、销毁” 四个阶段,Spring 提供了丰富的扩展点(如 InitializingBean、@PostConstruct)让开发者干预生命周期。
整个生命周期可拆解为 5 个核心阶段,结合 Spring 容器的工作机制,具体流程如下:
一、Spring Bean 生命周期总览(核心 5 阶段)
- 实例化(Instantiation) :创建 Bean 的原始实例(调用无参构造器或工厂方法);
- 属性填充(Populate) :为实例的成员变量赋值(依赖注入,如
@Autowired、setter注入); - 初始化(Initialization) :执行自定义初始化逻辑(如初始化方法、BeanPostProcessor 增强);
- 使用(In Use) :Bean 存入 Spring 容器,供应用程序调用(单例 Bean 常驻容器,原型 Bean 用完后由 GC 回收);
- 销毁(Destruction) :容器关闭时,执行自定义销毁逻辑(如释放资源、关闭连接)。
流程图简化:容器启动 → 实例化 → 属性填充 → 初始化(含增强)→ 就绪使用 → 容器关闭 → 销毁
二、生命周期详细拆解(含扩展点)
下面结合具体实现和扩展点,一步步拆解每个阶段的核心操作(以单例 Bean 为例,原型 Bean 无 “销毁阶段”):
1. 实例化(Instantiation):创建 Bean 原始对象
- 核心操作:Spring 容器通过反射调用 Bean 的 无参构造器(默认)或 工厂方法(如
@Bean标注的方法),生成一个 “空白” 的 Bean 实例(成员变量未赋值)。 - 注意:若 Bean 无无参构造器且未指定工厂方法,会抛出
NoSuchMethodException。
2. 属性填充(Populate):依赖注入
-
核心操作:Spring 容器根据配置(
@Autowired、@Resource、XML 配置的<property>等),为 Bean 的成员变量赋值,包括注入其他 Bean 依赖、基本类型值等。 -
关键细节:
- 依赖注入优先于初始化阶段;
- 若注入的依赖 Bean 未创建,Spring 会先递归创建依赖的 Bean,再注入当前 Bean。
3. 初始化(Initialization):执行自定义逻辑 + 增强
这是生命周期中最灵活的阶段,Spring 提供了 3 类初始化扩展点(执行顺序有严格要求),同时会触发 BeanPostProcessor 的增强逻辑。
(1)扩展点 1:Aware 接口回调(获取容器上下文)
若 Bean 实现了 Aware 系列接口,Spring 会自动注入对应的容器资源(回调顺序不固定,核心接口如下):
BeanNameAware:注入当前 Bean 的名称(setBeanName(String beanName));BeanFactoryAware:注入当前 Bean 所属的BeanFactory(setBeanFactory(BeanFactory beanFactory));ApplicationContextAware:注入 Spring 应用上下文ApplicationContext(setApplicationContext(ApplicationContext applicationContext));- 其他:
EnvironmentAware(注入环境配置)、ResourceLoaderAware(注入资源加载器)等。
示例:
@Component
public class MyBean implements BeanNameAware {
private String beanName;
@Override
public void setBeanName(String name) {
this.beanName = name; // Spring 自动注入 Bean 名称
}
}
(2)扩展点 2:BeanPostProcessor 前置增强(postProcessBeforeInitialization)
BeanPostProcessor 是 Spring 核心的 “Bean 后置处理器”,作用于 所有 Bean 的初始化前后,用于全局增强 Bean(如 AOP 代理、属性修改)。
- 执行时机:在 Aware 回调之后,自定义初始化方法之前;
- 核心方法:
Object postProcessBeforeInitialization(Object bean, String beanName)(返回增强后的 Bean 实例)。
示例(全局日志增强) :
@Component
public class LogBeanPostProcessor implements BeanPostProcessor {
// 初始化前执行
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【BeanPostProcessor前置】Bean " + beanName + " 即将初始化");
return bean; // 可返回原 Bean 或包装后的 Bean(如代理对象)
}
}
(3)扩展点 3:自定义初始化方法(3 种方式,执行顺序固定)
开发者可通过 3 种方式指定初始化逻辑,执行顺序为:@PostConstruct → InitializingBean → 自定义命名方法。
-
@PostConstruct注解(推荐) :JSR-250 标准注解,标注在非静态方法上,Spring 自动识别执行(无需配置)。@Component public class MyBean { @PostConstruct public void initByAnnotation() { System.out.println("【@PostConstruct】执行初始化逻辑"); } } -
实现
InitializingBean接口:Spring 内置接口,重写afterPropertiesSet()方法(依赖注入完成后执行)。@Component public class MyBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("【InitializingBean】执行初始化逻辑"); } } -
自定义命名方法(XML / 注解配置) :
- 注解方式:
@Bean(initMethod = "initByConfig")或@Scope(initMethod = "initByConfig"); - XML 方式:
<bean id="myBean" class="com.example.MyBean" init-method="initByConfig"/>。
public class MyBean { public void initByConfig() { System.out.println("【自定义方法】执行初始化逻辑"); } } - 注解方式:
(4)扩展点 4:BeanPostProcessor 后置增强(postProcessAfterInitialization)
- 执行时机:在所有自定义初始化方法之后;
- 核心作用:生成 AOP 代理对象(Spring AOP 的核心实现点)—— 若当前 Bean 被切面匹配,会在此阶段生成代理对象,替代原始 Bean 存入容器。
示例:
@Component
public class LogBeanPostProcessor implements BeanPostProcessor {
// 初始化后执行
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【BeanPostProcessor后置】Bean " + beanName + " 初始化完成");
return bean; // 若为 AOP 场景,返回代理对象
}
}
4. 使用(In Use):Bean 就绪
- 单例 Bean:初始化完成后,存入 Spring 容器的单例池(
singletonObjects),供应用程序通过getBean()或依赖注入调用,直到容器关闭; - 原型 Bean:初始化完成后,直接返回给调用者,Spring 容器不再管理其生命周期(后续销毁由 JVM 垃圾回收负责)。
5. 销毁(Destruction):释放资源
仅 单例 Bean 会执行销毁阶段(原型 Bean 无此阶段),触发时机为:
- 容器关闭时(如
ApplicationContext.close()、Spring Boot 应用停止); - 环境变量触发(如
@PreDestroy感知 JVM 关闭)。
销毁阶段同样支持 3 种自定义方式,执行顺序为:@PreDestroy → DisposableBean → 自定义命名销毁方法。
-
@PreDestroy注解(推荐) :JSR-250 标准注解,标注在非静态方法上,容器关闭前执行。@Component public class MyBean { @PreDestroy public void destroyByAnnotation() { System.out.println("【@PreDestroy】执行销毁逻辑(释放连接)"); } } -
实现
DisposableBean接口:Spring 内置接口,重写destroy()方法。@Component public class MyBean implements DisposableBean { @Override public void destroy() throws Exception { System.out.println("【DisposableBean】执行销毁逻辑"); } } -
自定义命名销毁方法(XML / 注解配置) :
- 注解方式:
@Bean(destroyMethod = "destroyByConfig"); - XML 方式:
<bean id="myBean" class="com.example.MyBean" destroy-method="destroyByConfig"/>。
public class MyBean { public void destroyByConfig() { System.out.println("【自定义方法】执行销毁逻辑"); } } - 注解方式:
三、核心扩展点执行顺序总结(关键!)
初始化阶段扩展点执行顺序(从早到晚):Aware 接口回调 → BeanPostProcessor.postProcessBeforeInitialization → @PostConstruct → InitializingBean.afterPropertiesSet → 自定义 initMethod → BeanPostProcessor.postProcessAfterInitialization
销毁阶段扩展点执行顺序(从早到晚):@PreDestroy → DisposableBean.destroy → 自定义 destroyMethod
四、单例 Bean vs 原型 Bean 生命周期差异
| 对比维度 | 单例 Bean(默认) | 原型 Bean(@Scope("prototype")) |
|---|---|---|
| 实例创建时机 | 容器启动时(默认,可通过 @Lazy 延迟) | 每次 getBean() 或注入时创建 |
| 容器管理范围 | 全程管理(实例化→初始化→销毁) | 仅管理实例化→初始化,不管理销毁 |
| 销毁阶段 | 有(容器关闭时执行) | 无(由 JVM 垃圾回收) |
| 性能开销 | 低(复用一个实例) | 高(频繁创建销毁实例) |
| 线程安全风险 | 有(共享实例,需控制状态) | 无(每个线程持有独立实例) |
五、关键注意点
@PostConstruct/@PreDestroy兼容性:Spring 5+ 需引入javax.annotation-api依赖(JDK 9+ 已移除该包),否则注解不生效;- BeanPostProcessor 作用范围:对所有 Bean 生效(包括 Spring 内置 Bean),若需针对特定 Bean 增强,需在方法内判断
beanName或 Bean 类型; - AOP 代理时机:若 Bean 被切面匹配,
postProcessAfterInitialization会返回代理对象,后续调用的是代理对象而非原始 Bean; - 原型 Bean 依赖单例 Bean:单例 Bean 初始化时会注入原型 Bean 的 “当前实例”,后续不会自动刷新原型 Bean(需用
ObjectFactory动态获取最新实例)。
六、总结
Spring Bean 生命周期的核心是 “容器对 Bean 的全生命周期管理”,关键在于:
- 掌握 5 个核心阶段 和 扩展点执行顺序(尤其是初始化阶段的 4 个扩展点);
- 理解单例与原型 Bean 的生命周期差异;
- 灵活使用
@PostConstruct、BeanPostProcessor等扩展点,实现自定义增强(如日志、事务、资源释放)。
日常开发中,最常用的扩展方式是 @PostConstruct(初始化)和 @PreDestroy(销毁),无需依赖 Spring 内置接口,兼容性更好;若需全局增强(如所有 Bean 初始化日志),可使用 BeanPostProcessor。