后端-Spring-Bean生命周期
一篇讲清楚Spring Bean生命周期:设计思路 + 一个小例子
第一次看 Spring Bean 生命周期时,都会被一堆“步骤 / 接口 / 扩展点”搞懵:看完只剩下背诵,真写业务又不会用。其实它的核心就是把 “一个对象从出生到死亡” 这套流程标准化,并且在关键节点留出“钩子”,让你能把资源初始化、清理这些事放到正确的时间点执行。
先想一个“普通 Java 对象的生命周期”
在 Java 里创建并使用一个对象,抽象成几步就够了:
- 创建对象:new一个对象出来,但属性可能还是默认值(null、0…)。
- 属性赋值:给对象里的各种属性填上值。
- 初始化:属性有了以后,可能需要“基于这些属性做进一步准备”,比如计算派生属性、初始化资源(连接、文件、线程池等)。
- 使用对象:业务逻辑真正开始用它。
- 销毁对象:系统要停了 / 容器要关了,对象销毁前往往要释放资源、落库、关闭连接等。
一个最直观的例子:数据库连接池
- 创建:new 一个连接池对象。
- 赋值:设置 URL、用户名、密码等配置。
- 初始化:根据这些配置先创建若干连接,放进池里备用。
- 使用:业务从池里借连接、归还连接。
- 销毁:系统退出前关闭连接、释放资源。
Spring Bean 生命周期,本质上就是把这套流程搬进容器里,并且提供标准化扩展点。
Spring Bean 生命周期
Spring Bean 生命周期核心流程也可以记成五段:
实例化:Spring 通过反射创建 Bean 实例(把对象“扭出来”)。
属性赋值:依赖注入发生在这里,比如
@Autowired注入属性,本质就是容器把依赖找出来,再通过反射 / setter / 构造器把值塞进去。初始化:让 Bean 在“可用之前”做最后准备。Spring 把初始化拆成三段,是为了给框架/中间件留扩展点(比如 AOP 代理、统一增强、注解解析等),而业务开发通常只需要记住它们的相对位置:
①初始化前置处理:
BeanPostProcessor的前置回调(before)②初始化本身:真正写的初始化逻辑,例如:
@PostConstruct、配置init-method③初始化后置处理:
BeanPostProcessor的后置回调(after)对写业务最关键的一点:初始化方法(@PostConstruct / init-method)触发时,依赖注入通常已经完成,所以你可以安全使用
@Autowired注入进来的依赖去做准备工作。使用:业务代码通过注入或从容器获取 Bean 并使用。
销毁:容器关闭时,Bean 在消亡前完成资源释放、收尾工作。
- 实现接口:
DisposableBean#destroy() - 配置方法:
destroy-method
- 实现接口:
真正需要掌握的是:
(1) 什么时候属性已经注入完成?(初始化阶段开始之前)
(2) 什么时候适合初始化资源?(初始化回调里)
(3) 什么时候适合释放资源?(销毁回调里)
一个完整小例子:文件记录工具
需求:
- 系统运行过程中:把一些数据记录到本地文件
- 系统运行结束时:把文件路径 + 文件大小保存到数据库,方便后续查看
设计:
- 写一个
FileRecord类负责记录文件 - 它依赖一个
FileService,负责把文件信息存到数据库 - 生命周期落点:
- 初始化阶段:创建本地文件(
@PostConstruct) - 销毁前阶段:把文件路径和大小存库(
@PreDestroy)
- 初始化阶段:创建本地文件(
下面是一个示意代码:
1 |
|


