我们来详细说一下 Spring 中 Bean 的生命周期
Spring Bean 的生命周期是 Spring 容器管理 Bean 从创建到销毁的整个过程,是面试高频、日常开发中非常重要的知识点。
下面是目前最主流、最完整的 Spring Bean 生命周期 说明(基于 Spring 5/6 & Spring Boot 主流版本):
Bean 生命周期完整流程(文字版)
- 实例化前阶段(Instantiation Aware)
- BeanFactoryPostProcessor(容器级别)
- BeanDefinition 已经被加载并解析完成
- 实例化(Instantiation)
- 通过构造方法(或工厂方法)创建 Bean 实例(new)
- 实例化后立即执行(Aware 接口回调)
- BeanNameAware.setBeanName()
- BeanClassLoaderAware.setBeanClassLoader()
- BeanFactoryAware.setBeanFactory() (如果是 BeanFactoryAware)
- BeanPostProcessor 前置处理(非常重要)
- BeanPostProcessor.postProcessBeforeInitialization()
- 初始化前阶段
- @PostConstruct 注解的方法(最常用)
- InitializingBean.afterPropertiesSet() 方法
- 自定义的 init-method 方法(xml 或 @Bean(initMethod=…))
- BeanPostProcessor 后置处理
- BeanPostProcessor.postProcessAfterInitialization()
(AOP 代理就在这里生成)
- Bean 可以使用了
- 此时 Bean 已经完全初始化完成,放入容器单例池(或放入原型池)
- 容器关闭时销毁阶段
- @PreDestroy 注解的方法
- DisposableBean.destroy() 方法
- 自定义的 destroy-method 方法(xml 或 @Bean(destroyMethod=…))
用一张图来概括(最常见的面试画法)
BeanFactoryPostProcessor → BeanDefinition 准备好
↓
构造方法 / 工厂方法 → 实例化
↓
Aware 接口回调(BeanNameAware、BeanFactoryAware...)
↓
BeanPostProcessor.postProcessBeforeInitialization()
↓
@PostConstruct → InitializingBean.afterPropertiesSet() → init-method
↓
BeanPostProcessor.postProcessAfterInitialization() ← 这里完成 AOP 代理
↓
Bean 就绪(放入单例池 / 原型模式)
↓
容器关闭时:
@PreDestroy → DisposableBean.destroy() → destroy-method
代码示例(最常见的几种方式)
@Component
public class MyBean implements InitializingBean, DisposableBean {
private String name;
public MyBean() {
System.out.println("1. 构造方法执行");
}
@Autowired
public void setName(String name) {
this.name = name;
System.out.println("2. 属性注入完成,name = " + name);
}
@PostConstruct
public void initByPostConstruct() {
System.out.println("3. @PostConstruct 执行");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("4. InitializingBean.afterPropertiesSet 执行");
}
public void myInitMethod() {
System.out.println("5. 自定义 init-method 执行");
}
@PreDestroy
public void preDestroy() {
System.out.println("6. @PreDestroy 执行");
}
@Override
public void destroy() throws Exception {
System.out.println("7. DisposableBean.destroy 执行");
}
public void myDestroyMethod() {
System.out.println("8. 自定义 destroy-method 执行");
}
}
配置方式(@Bean 写法示例):
@Configuration
public class BeanConfig {
@Bean(initMethod = "myInitMethod", destroyMethod = "myDestroyMethod")
public MyBean myBean() {
return new MyBean();
}
}
常见面试问题与答案要点
Q1:BeanPostProcessor 和 BeanFactoryPostProcessor 的区别?
- BeanFactoryPostProcessor:容器启动阶段,对 BeanDefinition 进行修改(还没实例化)
- BeanPostProcessor:针对已经实例化的 Bean,在初始化前后做处理(最典型的就是 AOP 代理在这里生成)
Q2:AOP 代理是在生命周期的哪一步生成的?
答:BeanPostProcessor.postProcessAfterInitialization() 这一步
Q3:@PostConstruct 和 InitializingBean 的执行顺序?
答:@PostConstruct 先执行 → 然后才是 afterPropertiesSet()
Q4:为什么 Spring 推荐使用 @PostConstruct 而不是 InitializingBean?
答:
- @PostConstruct 更轻量,不需要实现接口
- 语义更清晰
- 可以用在任意方法上,不限于 afterPropertiesSet 这个名字
Q5:原型 Bean(scope=”prototype”)会执行销毁方法吗?
答:不会。Spring 容器不对 prototype Bean 负责销毁。
Q6:Bean 什么时候会被销毁?
答:只有 singleton 作用域的 Bean,在 ApplicationContext 关闭时才会调用销毁方法(close() 或 ConfigurableApplicationContext.close())
总结一句话
Spring Bean 生命周期的核心阶段可以概括为:
实例化 → 属性填充 → Aware 回调 → 初始化前 → 初始化 → 初始化后 → 使用 → 销毁
最常被问到的点集中在:
- Aware 接口
- @PostConstruct / InitializingBean / init-method 的顺序
- BeanPostProcessor 前后置
- AOP 代理生成时机
如果你想继续深入某个部分(比如详细源码流程、BeanPostProcessor 实现原理、循环依赖如何在生命周期中解决、懒加载 Bean 的生命周期等),随时告诉我,我可以继续展开。