SpringBoot面试题11-Bean的生命周期
一、bean的生命周期一览

【备注】:第四阶段:销毁 Bean
容器关闭时调用:
| 执行方式 | 示例 |
|---|---|
| @PreDestroy | 推荐写法 |
| DisposableBean.destroy() | 接口方式 |
| destroyMethod | @Bean 指定 |
二、代码详解


三、结构化小结:Spring 中 Bean 的生命周期
总:
Bean 的生命周期总体来说有 4 个阶段,分别有创建对象、初始化对象、使用对象以及销毁对象,而且这些工作大部分是交给 Bean 工厂的 doCreateBean 方法完成的。
分:
首先,在创建对象阶段,先调用构造方法实例化对象,对象有了后会填充该对象的内容,其实就是处理依赖注入。
其次,对象创建完毕后,需要做一些初始化(真正决定 Bean 的最终形态)的操作,在这里涉及到几个扩展点:
-
执行 Aware 感知接口的回调方法
-
执行 Bean 后置处理器的
postProcessBeforeInitialization方法 -
执行 InitializingBean 接口的回调(在这一步如果 Bean 中有标注了
@PostConstruct注解的方法,会先执行它) -
执行 Bean 后置处理器的
postProcessAfterInitialization。(如果有AOP切面,此时会返回代理对象)
把这些扩展点都执行完后,Bean 的初始化就完成了。
接下来,在使用阶段就是程序员从容器中获取该 Bean 使用即可。
最后,在容器销毁之前,会执行销毁对象,此时会执行 DisposableBean 接口的回调,这一步如果 Bean 中有标注了 @PreDestroy 接口的方法,会先执行它。
总:
简单总结一下,Bean 的生命周期共包含四个阶段,其中初始化对象和销毁对象我们程序员可以通过一些扩展点执行自己的代码。
四、全程图

Bean 的“初始化”本身指执行 @PostConstruct、afterPropertiesSet 和 initMethod 这些操作。
而 BeanPostProcessor 并不负责初始化,它只是围绕初始化前后提供“增强”的扩展点。
特别是 AOP 代理对象是在 postProcessAfterInitialization 阶段生成并替换的。
4-1、分步骤详细版
① 加载 BeanDefinition(类信息 → 配方)
此时还没有创建对象,只是把类扫描成“说明书”。
就像做菜前先写菜单。
② 实例化 Instantiate(创建对象)
底层其实就是调用构造方法 new 出对象。
UserService userService = new UserService();
但此时对象内部依赖还没注入。
③ 依赖注入 Populate(@Autowired / @Resource)
通过 BeanFactory 递归注入依赖,保证每个对象能拿到它需要的成员对象。
@Autowired
OrderDao orderDao;
就像新员工入职后先分配电脑、工牌。
④ 执行 BeanPostProcessor — 初始化前
这个阶段非常重要!
方法:
postProcessBeforeInitialization(bean, beanName)
处理 @Autowired、@Resource、@Value 的依赖注入逻辑就在这里完成。
⑤ 初始化 Init(Bean 自己做准备工作)
Spring 提供了 三种方式 来写初始化逻辑,它们都会在 “初始化阶段” 执行:
| 方式 | 触发时机 | 示例 |
|---|---|---|
@PostConstruct | 最先执行 | 方法上加注解 |
InitializingBean.afterPropertiesSet() | 其次执行 | 实现接口 |
<bean init-method="xxx"> / @Bean(initMethod="xxx") | 最后执行 | XML 或 Java Config 指定 |
比如加载缓存、读取配置、建连接池。
⑥ 执行 BeanPostProcessor — 初始化后(AOP 就在这一步完成)⭐
方法:
postProcessAfterInitialization(bean, beanName)
AOP 动态代理就是在这一阶段“换掉 Bean 返回代理对象”:
| 如果类有接口 | JDK 动态代理 |
| 如果类没有接口 | CGLIB 代理 |
这是 Spring 最精华的点。
⑦ Bean 可以被业务代码使用
这时 Bean 已经完全就绪,进入正常工作阶段。
⑧ 销毁 Destroy(容器关闭时)
销毁也有 3 种方式:
| 方式 | 示例 |
|---|---|
| @PreDestroy | 推荐 |
DisposableBean.destroy() | 回调接口 |
destroyMethod 属性 | 自定义销毁方法 |
用来释放资源,例如:
-
关闭数据库连接
-
关闭线程池
-
清理缓存
