bigywater.tech
Spring · 3

Bean 生命周期:Aware、@PostConstruct、InitializingBean 与销毁回调的顺序

一个 Bean 从构造器到销毁,@PostConstruct、afterPropertiesSet、initMethod 到底谁先谁后?Aware 回调排在哪?prototype 会不会被销毁?初始化失败了销毁回调还会不会调用?这篇让一个 Bean 带上所有常见回调,在 Spring Framework 7.0.9 上把顺序逐个记下来。

15 个
singleton 创建阶段的回调个数(从 BPP.postProcessBeforeInstantiation 到 postProcessAfterInitialization)
0 个
prototype 的 Bean 在容器关闭时被调用的销毁回调数
第 12 个
@PostConstruct 在 15 个创建回调中的位置

完整的顺序

实测 · 本机执行输出
  --- 创建阶段(从构造器到 BeanPostProcessor.after)
   1.   [BPP] postProcessBeforeInstantiation
   2. 构造器 Life(Dep)
   3.   [BPP] postProcessAfterInstantiation
   4.   [BPP] postProcessProperties
   5. @Autowired setter setDep2
   6. BeanNameAware.setBeanName(life)
   7. BeanClassLoaderAware.setBeanClassLoader
   8. BeanFactoryAware.setBeanFactory
   9. EnvironmentAware.setEnvironment
  10. ApplicationContextAware.setApplicationContext
  11.   [BPP] postProcessBeforeInitialization
  12. @PostConstruct
  13. InitializingBean.afterPropertiesSet
  14. @Bean(initMethod) customInit
  15.   [BPP] postProcessAfterInitialization
  --- c.close() 之后
   1. @PreDestroy
   2. DisposableBean.destroy
   3. @Bean(destroyMethod) customDestroy

实例化前、构造器、注入、Aware、BPP.before、@PostConstruct、afterPropertiesSet、initMethod、BPP.after,销毁是反向的三个回调。

prototype

实测 · 本机执行输出
  --- 两次 getBean(prototype)
   1. 构造器 Life(Dep)
   2. @Autowired setter setDep2
   3. BeanNameAware.setBeanName(life)
   4. BeanClassLoaderAware.setBeanClassLoader
   5. BeanFactoryAware.setBeanFactory
   6. EnvironmentAware.setEnvironment
   7. ApplicationContextAware.setApplicationContext
   8. @PostConstruct
   9. InitializingBean.afterPropertiesSet
  10. 构造器 Life(Dep)
  11. @Autowired setter setDep2
  12. BeanNameAware.setBeanName(life)
  13. BeanClassLoaderAware.setBeanClassLoader
  14. BeanFactoryAware.setBeanFactory
  15. EnvironmentAware.setEnvironment
  16. ApplicationContextAware.setApplicationContext
  17. @PostConstruct
  18. InitializingBean.afterPropertiesSet
  --- c.close() 之后(prototype 的销毁回调)

容器只负责创建,不持有、不销毁 prototype 实例。

销毁方法推断

实测 · 本机执行输出
  --- c.close() 之后
   1. Closer.close() 被调用(没有任何配置)

@Bean 返回的对象有 close() 时,即使没配置也会在关闭时被调用;destroyMethod 设成空串可以关掉。

初始化失败

实测 · 本机执行输出
  --- 初始化抛异常的 Bean
   1. 构造器 Boom
   2. Boom.@PostConstruct 抛异常
   3. refresh 抛出 BeanCreationException ← IllegalStateException: 初始化失败

@PostConstruct 抛异常的 Bean 不会被登记销毁,@PreDestroy 不会被调用。

分步演示

Bean 的生命周期
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动。用不带 Boot 的 Spring Framework 7.0.9 的 AnnotationConfigApplicationContext;回调用同一个列表记录,只有顺序,没有测时间
    • 没有验证:@Lazy、@DependsOn 对顺序的影响;SmartInitializingSingleton 与 SmartLifecycle 的位置(见上一篇的时间线);Boot 的上下文里多出来的 BeanPostProcessor 对顺序的影响;XML 方式配置的 init-method / destroy-method;作用域为 request / session 的 Bean 的销毁
    京ICP备2026067502号-1京公网安备11010502063487号