文章目录
- 🌱 《Spring IOC核心:Bean生命周期全解析》
- 1️⃣ 引言:Bean 生命周期为什么重要?
- 2️⃣ Bean 生命周期概览(图示 + 简要说明)
- 3️⃣ 每一步详细解析(源码理解 + 示例)
- 3.1 🧱 实例化(构造函数)
- 3.2 🧩 属性注入(Setter、@Value、@Autowired)
- 3.3 🔎 Aware 接口(Bean 开始“认识环境”)
- 3.4 ⚙️ 初始化阶段(核心阶段!)
- ✅ 方式1:实现 InitializingBean
- ✅ 方式2:使用 @PostConstruct
- ✅ 方式3:init-method 配置(XML 或 @Bean)
- ✅ BeanPostProcessor:初始化前后增强
- 3.5 🧑🔧 使用阶段(容器托管中)
- 3.6 💣 销毁阶段
- ✅ 方式1:实现 DisposableBean
- ✅ 方式2:使用 @PreDestroy
- ✅ 方式3:destroy-method 配置
- 4️⃣ 实战演示:一个 Bean 完整生命周期打印示例
- 5️⃣ 常见误区与调试技巧
- 6️⃣ 总结 & 推荐实践
- 📘 延伸阅读
🌱 《Spring IOC核心:Bean生命周期全解析》
目标读者:
使用 Spring 的 Java 后端开发者,
想深入理解 Bean 的创建、初始化、销毁全过程,
以写出更加健壮、可控、可调试的应用代码。
1️⃣ 引言:Bean 生命周期为什么重要?
Bean,不是你
new
出来的,而是 Spring 创建并“托管”的!
在 Spring 框架中,Bean 是最核心的组件之一,但我们很多时候对它的 “出生 → 成长 → 退休” 过程了解得并不完整。
类比一下:
Spring 就像一个“高级托儿所”,Bean 是被托管的小朋友,从出生到离园都有严格的流程规范。
理解这个生命周期,不仅能帮助我们进行框架扩展、调试 Bug,更是理解 Spring “魔法”的第一步!
2️⃣ Bean 生命周期概览(图示 + 简要说明)
┌────────────┐│ 实例化 Instantiation└────┬───────┘↓┌────────┴────────┐│ 属性填充 Populate│└────────┬────────┘↓┌────────────┴────────────┐│ Aware 回调(BeanNameAware等)└────────────┬────────────┘↓┌────────────┴────────────┐│ 初始化:@PostConstruct / init-method│ + BeanPostProcessor 执行└────────────┬────────────┘↓┌────────┴────────┐│ Bean 被使用中 │└────────┬────────┘↓┌────────────┴────────────┐│ 销毁:@PreDestroy / destroy-method└─────────────────────────┘
3️⃣ 每一步详细解析(源码理解 + 示例)
3.1 🧱 实例化(构造函数)
Spring 首先通过 构造函数反射 实例化 Bean。
public class MyBean {public MyBean() {System.out.println("1️⃣ 实例化阶段");}
}
3.2 🧩 属性注入(Setter、@Value、@Autowired)
Spring 在实例化后,为 Bean 注入属性。
@Component
public class MyBean {@Value("${my.value:default}")private String value;@Autowiredprivate Dependency dependency;public void setValue(String value) {System.out.println("2️⃣ 属性注入:" + value);this.value = value;}@Autowiredpublic void setDependency(Dependency dependency) {System.out.println("2️⃣ 属性注入:依赖注入完成");this.dependency = dependency;}
}
3.3 🔎 Aware 接口(Bean 开始“认识环境”)
Bean 想知道自己叫什么、谁在托管我、我在哪个容器中?就实现这些接口。
@Component
public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {public void setBeanName(String name) {System.out.println("3️⃣ BeanNameAware:我的名字是 " + name);}public void setBeanFactory(BeanFactory factory) {System.out.println("3️⃣ BeanFactoryAware:我被 BeanFactory 托管");}public void setApplicationContext(ApplicationContext ctx) {System.out.println("3️⃣ ApplicationContextAware:我已感知到容器");}
}
3.4 ⚙️ 初始化阶段(核心阶段!)
Spring 让你“准备就绪”,可以做初始化逻辑了。
✅ 方式1:实现 InitializingBean
@Override
public void afterPropertiesSet() throws Exception {System.out.println("4️⃣ InitializingBean:属性注入后初始化");
}
✅ 方式2:使用 @PostConstruct
@PostConstruct
public void init() {System.out.println("4️⃣ @PostConstruct:初始化方法执行");
}
✅ 方式3:init-method 配置(XML 或 @Bean)
@Bean(initMethod = "init")
public MyBean myBean() {return new MyBean();
}
✅ BeanPostProcessor:初始化前后增强
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {public Object postProcessBeforeInitialization(Object bean, String name) {System.out.println("⚙️ Before Init: " + name);return bean;}public Object postProcessAfterInitialization(Object bean, String name) {System.out.println("⚙️ After Init: " + name);return bean;}
}
3.5 🧑🔧 使用阶段(容器托管中)
此阶段 Bean 被容器管理、可被其他组件注入、调用。
@Component
public class UserService {@Autowiredprivate MyBean myBean;public void use() {System.out.println("5️⃣ Bean 正在被使用中");}
}
3.6 💣 销毁阶段
Spring 容器关闭时,执行销毁逻辑。
✅ 方式1:实现 DisposableBean
@Override
public void destroy() throws Exception {System.out.println("6️⃣ DisposableBean:销毁中");
}
✅ 方式2:使用 @PreDestroy
@PreDestroy
public void destroyMethod() {System.out.println("6️⃣ @PreDestroy:销毁逻辑");
}
✅ 方式3:destroy-method 配置
@Bean(destroyMethod = "cleanup")
public MyBean myBean() {return new MyBean();
}
⚠️ 注意:@Scope(“prototype”) 的 Bean 容器不负责销毁!需手动释放资源。
4️⃣ 实战演示:一个 Bean 完整生命周期打印示例
@Component
public class LifeCycleBean implements BeanNameAware, InitializingBean, DisposableBean {public LifeCycleBean() {System.out.println("1️⃣ 构造方法执行:实例化");}@Autowiredpublic void setDependency(Dependency dep) {System.out.println("2️⃣ 属性注入");}@Overridepublic void setBeanName(String name) {System.out.println("3️⃣ 感知容器:我的名字是 " + name);}@PostConstructpublic void postConstruct() {System.out.println("4️⃣ 初始化:@PostConstruct");}@Overridepublic void afterPropertiesSet() {System.out.println("4️⃣ 初始化:afterPropertiesSet");}@PreDestroypublic void preDestroy() {System.out.println("6️⃣ 销毁:@PreDestroy");}@Overridepublic void destroy() {System.out.println("6️⃣ 销毁:destroy()");}
}
控制台输出:
1️⃣ 构造方法执行:实例化
2️⃣ 属性注入
3️⃣ 感知容器:我的名字是 lifeCycleBean
4️⃣ 初始化:@PostConstruct
4️⃣ 初始化:afterPropertiesSet
⚙️ Bean 使用中...
6️⃣ 销毁:@PreDestroy
6️⃣ 销毁:destroy()
5️⃣ 常见误区与调试技巧
问题描述 | 可能原因 |
---|---|
@PostConstruct 不执行 | Bean 没被容器管理,或被 @Configuration 注册成了 Lite 模式 |
BeanPostProcessor 顺序异常 | 实现了多个 BPP 接口但未排序,可实现 Ordered 解决 |
原型 Bean 不执行 destroy | @Scope("prototype") 的 Bean 不受容器销毁管理 |
生命周期日志没打印 | @Component 没扫到;或被懒加载;或依赖未注入 |
6️⃣ 总结 & 推荐实践
- Bean 生命周期是 Spring 提供扩展能力的核心入口;
- 推荐使用 @PostConstruct 和 @PreDestroy 进行初始化/销毁管理;
- 多个初始化方式优先级为:@PostConstruct > InitializingBean > init-method;
- 掌握 Bean 生命周期 = 掌握 Spring 魔法的第一步!
📘 延伸阅读
- Spring 源码 AbstractBeanFactory
- 《Spring 实战》第 4 章 Bean 生命周期
- 官方文档:Bean Lifecycle