引言:为什么需要了解Spring Bean的生命周期?
在日常开发中,我们经常使用@Component、@Service、@Autowired等注解,Spring会帮我们自动创建和管理对象。但你是否想过:
- Bean是什么时候创建的?
- 它的属性是什么时候注入的?
- 我们能不能在Bean初始化前后做点什么?
- 容器关闭时,Bean是如何被销毁的?
这些问题,正是Spring Bean生命周期要回答的。
Spring Bean 生命周期全流程

流程详细说明
容器启动,Bean定义加载
Spring容器启动时,会读取配置(如XML、注解、Java Config),将每一个Bean的定义信息加载为BeanDefinition。
实例化Bean
通过反射或工厂方法创建Bean的实例(此时还未注入属性)。
注入属性(依赖注入)
根据Bean定义中的属性配置,Spring自动完成依赖注入(如@Autowired、@Resource等)。
处理Aware接口
如果Bean实现了以下接口,Spring会注入相应的资源:
BeanNameAware:注入当前Bean的IDBeanFactoryAware:注入当前BeanFactoryApplicationContextAware:注入当前ApplicationContext
BeanPostProcessor前置处理
所有Bean都会经过BeanPostProcessor的postProcessBeforeInitialization方法,允许我们在Bean初始化之前进行自定义增强(如代理、日志等)。
执行初始化方法
Spring支持多种初始化方式,按顺序执行:
@PostConstruct注解标注的方法InitializingBean接口的afterPropertiesSet()方法- 自定义
init-method(如XML或@Bean(initMethod="init"))
BeanPostProcessor后置处理
执行postProcessAfterInitialization方法,此时Bean已经完成初始化,可以进行最终包装或代理。
Bean准备就绪,投入使用
此时Bean已经完全初始化,可以被应用程序正常使用。
容器关闭,销毁Bean
当容器关闭时(如调用close()方法),Spring会销毁Bean,支持以下销毁方式:
@PreDestroy注解标注的方法DisposableBean接口的destroy()方法- 自定义
destroy-method
示例代码
容器日志
java
@Component
public class LifecycleDemo implements BeanNameAware, InitializingBean, DisposableBean {
@Override
public void setBeanName(String name) {
System.out.println("1. BeanNameAware.setBeanName: " + name);
}
@PostConstruct
public void postConstruct() {
System.out.println("2. @PostConstruct");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("3. InitializingBean.afterPropertiesSet");
}
public void customInit() {
System.out.println("4. 自定义init-method");
}
@PreDestroy
public void preDestroy() {
System.out.println("5. @PreDestroy");
}
@Override
public void destroy() throws Exception {
System.out.println("6. DisposableBean.destroy");
}
public void customDestroy() {
System.out.println("7. 自定义destroy-method");
}
}
配置类:
java
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifecycleDemo lifecycleDemo() {
return new LifecycleDemo();
}
}
启动类:
java
public class LifecycleDemoRunner {
public static void main(String[] args) {
try (AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class)) {
System.out.println("=== 容器启动完成 ===");
LifecycleDemo bean = context.getBean(LifecycleDemo.class);
System.out.println("=== Bean已获取,准备关闭容器 ===");
}
}
}
运行结果
java
1. BeanNameAware.setBeanName: lifecycleDemo
2. @PostConstruct
3. InitializingBean.afterPropertiesSet
4. 自定义init-method
容器启动完成,Bean已就绪
准备关闭容器...
5. @PreDestroy
6. DisposableBean.destroy
7. 自定义destroy-method
输出顺序分析
| 输出顺序 | 执行阶段 | 说明 |
|---|---|---|
| 1 | Aware接口 | 容器注入Bean名称 |
| 2 | 初始化前 | JSR-250规范的@PostConstruct |
| 3 | 初始化中 | Spring的InitializingBean接口 |
| 4 | 初始化中 | 自定义init-method |
| --- | 使用阶段 | 容器启动完成,Bean正常工作 |
| 5 | 销毁前 | JSR-250规范的@PreDestroy |
| 6 | 销毁中 | Spring的DisposableBean接口 |
| 7 | 销毁中 | 自定义destroy-method |
执行顺序总结
Aware接口 → @PostConstruct → afterPropertiesSet → init-method → 使用中 → @PreDestroy → destroy → destroy-method