说下 Spring Bean 的生命周期?从实例化到销毁的完整旅程
2026/6/8 23:23:49 网站建设 项目流程

说下 Spring Bean 的生命周期?从实例化到销毁的完整旅程

    • 1. 先看结论(速记版)
    • 2. 完整生命周期流程图
    • 3. 生命周期详细解析
      • 3.1 第一阶段:实例化(Instantiation)
      • 3.2 第二阶段:属性填充(Population)
      • 3.3 第三阶段:初始化前(Before Initialization)
      • 3.4 第四阶段:初始化(Initialization)
      • 3.5 第五阶段:初始化后(After Initialization)
      • 3.6 第六阶段:使用(In Use)
      • 3.7 第七阶段:销毁(Destruction)
    • 4. 完整代码示例:贯穿整个生命周期
    • 5. 各扩展点对比表
      • 5.1 初始化阶段对比
      • 5.2 销毁阶段对比
    • 6. 常见面试追问
      • Q1:AOP 代理在哪个阶段生成?
      • Q2:为什么 AOP 不能在更早的阶段生成?
      • Q3:`@PostConstruct` 和 `afterPropertiesSet` 有什么区别?
      • Q4:如果一个 Bean 既实现了 `InitializingBean` 又指定了 `init-method`,执行顺序?
      • Q5:BeanPostProcessor 和 BeanFactoryPostProcessor 的区别?
    • 7. 生命周期中的设计模式
    • 8. 记忆口诀
    • 9. 思考题

🌺The Begin🌺点点关注,收藏不迷路🌺

⬇ ⬇ 底部 ⬇ ⬇

Spring Bean 的生命周期是面试中的“核弹级”问题,也是理解 Spring 框架的核心钥匙。本文将按照时间顺序,从 Bean 的创建到销毁,完整讲解每个阶段的核心方法、扩展点和底层原理。


1. 先看结论(速记版)

阶段核心动作关键扩展点
1. 实例化调用构造器创建对象BeanPostProcessor前置
2. 属性填充注入依赖(@Autowired)InstantiationAwareBeanPostProcessor
3. 初始化前Bean 初始化前回调@PostConstructBeanPostProcessor.postProcessBeforeInitialization
4. 初始化执行自定义初始化InitializingBean.afterPropertiesSet()@Bean(initMethod)
5. 初始化后Bean 初始化后回调BeanPostProcessor.postProcessAfterInitialization、AOP 代理生成
6. 使用正常运行业务调用
7. 销毁销毁前回调@PreDestroyDisposableBean.destroy()@Bean(destroyMethod)

一句话总结:
构造器 → 注入属性 → 初始化前 → 初始化 → 初始化后 → 使用 → 销毁


2. 完整生命周期流程图

渲染错误:Mermaid 渲染失败: Parse error on line 14: ...tion] F --> G[@PostConstruct 方法执 ----------------------^ Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'LINK_ID'

3. 生命周期详细解析

3.1 第一阶段:实例化(Instantiation)

时机:容器启动,根据BeanDefinition创建 Bean 实例

核心动作:

  • 通过构造器或工厂方法创建对象
  • 此时对象属性全为默认值(null/0/false)
  • 只是分配了内存空间
@ComponentpublicclassUserService{privateStringname;// 此时为 null// 实例化时调用构造器publicUserService(){System.out.println("1. 实例化:执行构造器");}}

关键扩展点:

@ComponentpublicclassMyInstantiationAwareBeanPostProcessorimplementsInstantiationAwareBeanPostProcessor{@OverridepublicObjectpostProcessBeforeInstantiation(Class<?>beanClass,StringbeanName){// 实例化前回调,可返回代理对象替换原始 Beanif(beanName.equals("userService")){System.out.println("实例化前:可以返回代理对象");}returnnull;// 返回 null 表示正常实例化}}

3.2 第二阶段:属性填充(Population)

时机:对象实例化后,注入依赖

核心动作:

  • @Autowired@Value@Resource等注解注入
  • XML 配置的<property>注入
  • Aware 接口注入(BeanNameAware、ApplicationContextAware 等)
@ComponentpublicclassUserServiceimplementsBeanNameAware,ApplicationContextAware{@AutowiredprivateOrderServiceorderService;// 依赖注入privateStringbeanName;privateApplicationContextapplicationContext;@OverridepublicvoidsetBeanName(Stringname){this.beanName=name;System.out.println("2. 属性填充:BeanNameAware - "+name);}@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext){this.applicationContext=applicationContext;System.out.println("2. 属性填充:ApplicationContextAware");}}

关键 Aware 接口执行顺序:

Aware 接口注入内容执行时机
BeanNameAwareBean 在容器中的名称属性填充后
BeanClassLoaderAware类加载器属性填充后
BeanFactoryAwareBeanFactory 实例属性填充后
ApplicationContextAwareApplicationContext属性填充后
EnvironmentAwareEnvironment 配置属性填充后
ResourceLoaderAwareResourceLoader属性填充后

3.3 第三阶段:初始化前(Before Initialization)

时机:属性填充完成后,执行自定义初始化逻辑之前

核心动作:

  • BeanPostProcessor.postProcessBeforeInitialization()
  • @PostConstruct标注的方法
@ComponentpublicclassUserService{@PostConstructpublicvoidinit(){System.out.println("3. 初始化前:@PostConstruct 方法执行");}}// 或通过 BeanPostProcessor@ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofUserService){System.out.println("3. 初始化前:BeanPostProcessor.before");}returnbean;}}

执行顺序:

1.BeanPostProcessor.postProcessBeforeInitialization()2.@PostConstruct标注的方法

3.4 第四阶段:初始化(Initialization)

时机:执行自定义初始化逻辑

核心动作:

  • InitializingBean.afterPropertiesSet()
  • 自定义init-method(如@Bean(initMethod="myInit")
@ComponentpublicclassUserServiceimplementsInitializingBean{@OverridepublicvoidafterPropertiesSet()throwsException{System.out.println("4. 初始化:InitializingBean.afterPropertiesSet");}// 自定义初始化方法publicvoidmyCustomInit(){System.out.println("4. 初始化:自定义 init-method");}}// 配置类中指定@ConfigurationpublicclassAppConfig{@Bean(initMethod="myCustomInit")publicUserServiceuserService(){returnnewUserService();}}

执行顺序:

1.InitializingBean.afterPropertiesSet()2.自定义 init-method

3.5 第五阶段:初始化后(After Initialization)

时机:初始化完成后,Bean 正式可用的最后一道工序

核心动作:

  • BeanPostProcessor.postProcessAfterInitialization()
  • AOP 代理生成(关键!)
@ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(beaninstanceofUserService){System.out.println("5. 初始化后:BeanPostProcessor.after");// 这里可以返回代理对象替换原 Bean// 例如:AOP 在这里生成代理}returnbean;}}

AOP 代理生成时机:

// AbstractAutoProxyCreator 是 BeanPostProcessor 的实现publicclassAbstractAutoProxyCreatorextendsProxyProcessorSupportimplementsSmartInstantiationAwareBeanPostProcessor,BeanFactoryAware{@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){// 检查是否需要 AOP 代理if(beaninstanceofAdvised){returnbean;}// 如果需要代理,返回代理对象returnwrapIfNecessary(bean,beanName);}}

3.6 第六阶段:使用(In Use)

时机:Bean 完全初始化完毕,放入singletonObjects一级缓存

@ServicepublicclassOrderService{@AutowiredprivateUserServiceuserService;// 使用已初始化完成的 BeanpublicvoiddoSomething(){userService.sayHello();// 正常业务调用}}

3.7 第七阶段:销毁(Destruction)

时机:容器关闭时

核心动作:

  • @PreDestroy标注的方法
  • DisposableBean.destroy()
  • 自定义destroy-method
@ComponentpublicclassUserServiceimplementsDisposableBean{@PreDestroypublicvoidpreDestroy(){System.out.println("7. 销毁前:@PreDestroy 执行");}@Overridepublicvoiddestroy()throwsException{System.out.println("7. 销毁:DisposableBean.destroy");}publicvoidmyCustomDestroy(){System.out.println("7. 销毁:自定义 destroy-method");}}// 配置类@ConfigurationpublicclassAppConfig{@Bean(destroyMethod="myCustomDestroy")publicUserServiceuserService(){returnnewUserService();}}

执行顺序:

1.@PreDestroy标注的方法2.DisposableBean.destroy()3.自定义 destroy-method

4. 完整代码示例:贯穿整个生命周期

@ComponentpublicclassLifecycleDemoimplementsBeanNameAware,BeanClassLoaderAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{privateStringname;@AutowiredprivateOrderServiceorderService;// ========== 1. 实例化 ==========publicLifecycleDemo(){System.out.println("【1】实例化:构造器执行");}// ========== 2. 属性填充 ==========@AutowiredpublicvoidsetName(@Value("testBean")Stringname){this.name=name;System.out.println("【2】属性填充:@Value 注入 name = "+name);}@OverridepublicvoidsetBeanName(Stringname){System.out.println("【2】属性填充:BeanNameAware - "+name);}@OverridepublicvoidsetBeanClassLoader(ClassLoaderclassLoader){System.out.println("【2】属性填充:BeanClassLoaderAware");}@OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{System.out.println("【2】属性填充:BeanFactoryAware");}@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{System.out.println("【2】属性填充:ApplicationContextAware");}// ========== 3. 初始化前 ==========@PostConstructpublicvoidpostConstruct(){System.out.println("【3】初始化前:@PostConstruct 执行");}// ========== 4. 初始化 ==========@OverridepublicvoidafterPropertiesSet()throwsException{System.out.println("【4】初始化:InitializingBean.afterPropertiesSet 执行");}// 自定义 init-method(需在 @Bean 中指定)publicvoidcustomInit(){System.out.println("【4】初始化:自定义 init-method 执行");}// ========== 5. 初始化后 ==========// BeanPostProcessor.postProcessAfterInitialization 会在这里执行// ========== 6. 使用 ==========publicvoiddoWork(){System.out.println("【6】使用:业务方法执行");}// ========== 7. 销毁 ==========@PreDestroypublicvoidpreDestroy(){System.out.println("【7】销毁前:@PreDestroy 执行");}@Overridepublicvoiddestroy()throwsException{System.out.println("【7】销毁:DisposableBean.destroy 执行");}publicvoidcustomDestroy(){System.out.println("【7】销毁:自定义 destroy-method 执行");}}// 配置类@ConfigurationpublicclassLifecycleConfig{@Bean(initMethod="customInit",destroyMethod="customDestroy")publicLifecycleDemolifecycleDemo(){returnnewLifecycleDemo();}}// BeanPostProcessor 示例@ComponentpublicclassCustomBeanPostProcessorimplementsBeanPostProcessor{@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofLifecycleDemo){System.out.println("【3】初始化前:BeanPostProcessor.before");}returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(beaninstanceofLifecycleDemo){System.out.println("【5】初始化后:BeanPostProcessor.after");}returnbean;}}

运行输出:

【1】实例化:构造器执行 【2】属性填充:@Value 注入 name = testBean 【2】属性填充:BeanNameAware - lifecycleDemo 【2】属性填充:BeanClassLoaderAware 【2】属性填充:BeanFactoryAware 【2】属性填充:ApplicationContextAware 【3】初始化前:BeanPostProcessor.before 【3】初始化前:@PostConstruct 执行 【4】初始化:InitializingBean.afterPropertiesSet 执行 【4】初始化:自定义 init-method 执行 【5】初始化后:BeanPostProcessor.after 【6】使用:业务方法执行 【7】销毁前:@PreDestroy 执行 【7】销毁:DisposableBean.destroy 执行 【7】销毁:自定义 destroy-method 执行

5. 各扩展点对比表

5.1 初始化阶段对比

扩展方式执行阶段执行顺序使用场景
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation实例化前1返回代理对象替换原 Bean
BeanPostProcessor.postProcessBeforeInitialization初始化前2对所有 Bean 做统一处理
@PostConstruct初始化前3Bean 自己的初始化逻辑
InitializingBean.afterPropertiesSet初始化4实现接口做初始化
@Bean(initMethod)初始化5不侵入代码的初始化
BeanPostProcessor.postProcessAfterInitialization初始化后6AOP 代理生成、数据校验

5.2 销毁阶段对比

扩展方式执行阶段使用场景
@PreDestroy销毁前释放资源
DisposableBean.destroy销毁实现接口做清理
@Bean(destroyMethod)销毁不侵入代码的清理

6. 常见面试追问

Q1:AOP 代理在哪个阶段生成?

答:BeanPostProcessor.postProcessAfterInitialization阶段。Spring 的AbstractAutoProxyCreator实现了这个接口,在初始化后检查 Bean 是否需要代理,如果需要则返回代理对象替换原始 Bean。

Q2:为什么 AOP 不能在更早的阶段生成?

答:因为:

  1. 需要等待依赖注入完成
  2. 需要等待@PostConstruct等初始化完成
  3. 代理对象需要持有原始 Bean 的所有状态

Q3:@PostConstructafterPropertiesSet有什么区别?

对比@PostConstructafterPropertiesSet
标准JSR-250 标准Spring 专有
执行时机更早稍晚
依赖注入已完成已完成
推荐度✅ 推荐⚠️ Spring 耦合

Q4:如果一个 Bean 既实现了InitializingBean又指定了init-method,执行顺序?

答:afterPropertiesSet()先执行,init-method后执行。

// 执行顺序// 1. afterPropertiesSet()// 2. init-method

Q5:BeanPostProcessor 和 BeanFactoryPostProcessor 的区别?

对比BeanPostProcessorBeanFactoryPostProcessor
作用对象Bean 实例BeanDefinition
执行时机Bean 实例化后Bean 实例化前
典型应用AOP、@Autowired配置属性替换(@PropertySource)

7. 生命周期中的设计模式

设计模式应用场景源码体现
模板方法模式定义 Bean 创建流程AbstractAutowireCapableBeanFactory.doCreateBean()
工厂模式创建 Bean 实例BeanFactoryFactoryBean
策略模式不同实例化策略InstantiationStrategy
观察者模式容器事件监听ApplicationListener
责任链模式BeanPostProcessor 链List<BeanPostProcessor>

8. 记忆口诀

实例化先调构造,属性填充依赖到
Aware 接口注资源,PostConstruct 前奏绕
afterPropertiesSet 走,init-method 后续搞
后置处理 AOP 生,Bean 就绪业务跑
容器关闭要销毁,PreDestroy 最后扫


9. 思考题

// 问题:以下代码的执行顺序是什么?@ComponentpublicclassTestBeanimplementsInitializingBean,BeanPostProcessor{publicTestBean(){System.out.println("1");}@PostConstructpublicvoidpost(){System.out.println("2");}@OverridepublicvoidafterPropertiesSet(){System.out.println("3");}@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){System.out.println("4");returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){System.out.println("5");returnbean;}}

答案:

1 // 实例化 4 // 其他 Bean 初始化时会触发,但不会自己触发自己 2 // @PostConstruct 3 // afterPropertiesSet 5 // postProcessAfterInitialization

注意:BeanPostProcessor 自身也会被容器作为 Bean 处理,但它的执行时机是在其他 Bean 的初始化过程中,不是在自己初始化过程中调用自己的方法。


希望这篇文章能帮你彻底掌握 Spring Bean 的生命周期。如果觉得有用,欢迎点赞、收藏、转发!

👉 关注我,更多 Spring 源码干货持续更新中。


🌺The End🌺点点关注,收藏不迷路🌺

⬆ ⬆ 顶部 ⬆ ⬆

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询