说下 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 初始化前回调 | @PostConstruct、BeanPostProcessor.postProcessBeforeInitialization |
| 4. 初始化 | 执行自定义初始化 | InitializingBean.afterPropertiesSet()、@Bean(initMethod) |
| 5. 初始化后 | Bean 初始化后回调 | BeanPostProcessor.postProcessAfterInitialization、AOP 代理生成 |
| 6. 使用 | 正常运行 | 业务调用 |
| 7. 销毁 | 销毁前回调 | @PreDestroy、DisposableBean.destroy()、@Bean(destroyMethod) |
一句话总结:
构造器 → 注入属性 → 初始化前 → 初始化 → 初始化后 → 使用 → 销毁
2. 完整生命周期流程图
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 接口 | 注入内容 | 执行时机 |
|---|---|---|
BeanNameAware | Bean 在容器中的名称 | 属性填充后 |
BeanClassLoaderAware | 类加载器 | 属性填充后 |
BeanFactoryAware | BeanFactory 实例 | 属性填充后 |
ApplicationContextAware | ApplicationContext | 属性填充后 |
EnvironmentAware | Environment 配置 | 属性填充后 |
ResourceLoaderAware | ResourceLoader | 属性填充后 |
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-method3.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-method4. 完整代码示例:贯穿整个生命周期
@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 | 初始化前 | 3 | Bean 自己的初始化逻辑 |
InitializingBean.afterPropertiesSet | 初始化 | 4 | 实现接口做初始化 |
@Bean(initMethod) | 初始化 | 5 | 不侵入代码的初始化 |
BeanPostProcessor.postProcessAfterInitialization | 初始化后 | 6 | AOP 代理生成、数据校验 |
5.2 销毁阶段对比
| 扩展方式 | 执行阶段 | 使用场景 |
|---|---|---|
@PreDestroy | 销毁前 | 释放资源 |
DisposableBean.destroy | 销毁 | 实现接口做清理 |
@Bean(destroyMethod) | 销毁 | 不侵入代码的清理 |
6. 常见面试追问
Q1:AOP 代理在哪个阶段生成?
答:在BeanPostProcessor.postProcessAfterInitialization阶段。Spring 的AbstractAutoProxyCreator实现了这个接口,在初始化后检查 Bean 是否需要代理,如果需要则返回代理对象替换原始 Bean。
Q2:为什么 AOP 不能在更早的阶段生成?
答:因为:
- 需要等待依赖注入完成
- 需要等待
@PostConstruct等初始化完成 - 代理对象需要持有原始 Bean 的所有状态
Q3:@PostConstruct和afterPropertiesSet有什么区别?
| 对比 | @PostConstruct | afterPropertiesSet |
|---|---|---|
| 标准 | JSR-250 标准 | Spring 专有 |
| 执行时机 | 更早 | 稍晚 |
| 依赖注入 | 已完成 | 已完成 |
| 推荐度 | ✅ 推荐 | ⚠️ Spring 耦合 |
Q4:如果一个 Bean 既实现了InitializingBean又指定了init-method,执行顺序?
答:afterPropertiesSet()先执行,init-method后执行。
// 执行顺序// 1. afterPropertiesSet()// 2. init-methodQ5:BeanPostProcessor 和 BeanFactoryPostProcessor 的区别?
| 对比 | BeanPostProcessor | BeanFactoryPostProcessor |
|---|---|---|
| 作用对象 | Bean 实例 | BeanDefinition |
| 执行时机 | Bean 实例化后 | Bean 实例化前 |
| 典型应用 | AOP、@Autowired | 配置属性替换(@PropertySource) |
7. 生命周期中的设计模式
| 设计模式 | 应用场景 | 源码体现 |
|---|---|---|
| 模板方法模式 | 定义 Bean 创建流程 | AbstractAutowireCapableBeanFactory.doCreateBean() |
| 工厂模式 | 创建 Bean 实例 | BeanFactory、FactoryBean |
| 策略模式 | 不同实例化策略 | 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🌺点点关注,收藏不迷路🌺 ⬆ ⬆ 顶部 ⬆ ⬆ |