Spring Bean 生命周期线性执行顺序详解
(基于 Spring 6.x 版本,时间戳:2025 年 3 月 3 日 01:17)
一、完整生命周期流程图
实例化 → 属性注入 → Aware 回调 → BeanPostProcessor 前置 → 初始化 → BeanPostProcessor 后置 → 运行期 → 销毁
二、分阶段线性执行顺序
- 实例化阶段
- 触发条件:容器启动或首次请求 Bean 时
- 关键动作:
▸ 通过构造器/工厂方法创建对象实例
▸ 若实现 InstantiationAwareBeanPostProcessor 接口,优先执行 postProcessBeforeInstantiation()(可跳过默认实例化)
- 属性注入阶段
- 核心操作:
▸ 按类型/名称注入依赖(处理 @Autowired、@Resource)
▸ 解析占位符和 SpEL 表达式(@Value) - 扩展点:
▸ InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() (干预属性注入逻辑)
▸ InstantiationAwareBeanPostProcessor.postProcessProperties() (自定义属性处理)
- 核心操作:
- Aware 接口回调
- 执行顺序:
▸ BeanNameAware.setBeanName()
▸ BeanClassLoaderAware.setBeanClassLoader()
▸ BeanFactoryAware.setBeanFactory()
▸ 其他扩展 Aware 接口(如 EnvironmentAware, ApplicationContextAware)
- 执行顺序:
- BeanPostProcessor 前置处理
- 核心逻辑:
▸ 遍历所有 BeanPostProcessor 执行 postProcessBeforeInitialization()
▸ 处理 @PostConstruct 注解方法(通过 CommonAnnotationBeanPostProcessor 实现)
- 核心逻辑:
- 初始化阶段
- 执行顺序:
▸ InitializingBean.afterPropertiesSet()
▸ XML/注解声明的 init-method(如 @Bean(initMethod="customInit"))
- 执行顺序:
- BeanPostProcessor 后置处理
- 关键作用:
▸ 执行 postProcessAfterInitialization()
▸ 生成代理对象(如 AOP 在此阶段完成)
- 关键作用:
- 运行期阶段
- 状态特征:
▸ Bean 进入就绪状态,可被其他组件依赖
▸ 单例 Bean 驻留在 IoC 容器中,原型 Bean 每次请求新建实例
- 状态特征:
- 销毁阶段
- 逆序执行逻辑:
▸ @PreDestroy 注解方法
▸ DisposableBean.destroy()
▸ 自定义 destroy-method - 触发条件:
▸ 容器关闭(ConfigurableApplicationContext.close() )
▸ 仅针对单例 Bean 执行
- 逆序执行逻辑:
三、特殊场景执行差异
场景 | 差异点 |
---|---|
Prototype 作用域 Bean | 不执行销毁阶段(步骤 8),容器不跟踪其生命周期 |
延迟初始化 Bean | 步骤 1-6 在首次请求时触发,而非容器启动时 |
循环依赖 | 通过三级缓存提前暴露半成品 Bean,但初始化流程仍按完整顺序执行 |
四、调试与验证方法
- 日志观察:
public class DebugBean implements InitializingBean, DisposableBean { @PostConstruct public void post() { System.out.println("@PostConstruct 执行"); } @PreDestroy public void pre() { System.out.println("@PreDestroy 执行"); } @Override public void afterPropertiesSet() { System.out.println("InitializingBean 回调"); } @Override public void destroy() { System.out.println("DisposableBean 回调"); } }
- 断点追踪:
▸ 在 AbstractAutowireCapableBeanFactory 的 initializeBean()方法设置断点
▸ 监控 BeanPostProcessor 实现类的执行堆栈
五、设计启示
- 扩展点选择策略:
- 优先使用 @PostConstruct/@PreDestroy(JSR-250 标准)
- 避免同时实现 InitializingBean 和定义 init-method(导致执行顺序混淆)
- 性能优化:
- 减少 BeanPostProcessor 数量(影响所有 Bean 的初始化速度)
- 对非必要 Aware 接口实现保持谨慎(增加耦合度)
总结:Spring Bean 生命周期是一个严格线性但高度可扩展的流程,理解其执行顺序对解决依赖注入异常、优化启动性能、实现高级扩展功能(如自定义作用域)具有关键意义。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于