谈一谈Sping Bean的生命周期?
Spring Bean 生命周期核心概念
简单来说,Spring Bean 的生命周期 就是 Bean 从「被 Spring 容器创建」到「最终被销毁」的全流程。Spring 容器会接管 Bean 的创建、初始化、依赖注入、使用、销毁等所有环节,我们可以通过各种扩展点(如接口、注解)介入这个流程,实现自定义逻辑。
Spring Bean 完整生命周期(8 个核心阶段)
Bean生命周期:
代码示例:
示例Bean:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 自定义 Bean,实现所有生命周期扩展接口
*/
public class UserBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
// 模拟依赖注入的属性
private String username;
// ------------------- 阶段1:实例化 Bean -------------------
// Spring 通过反射调用无参构造器创建 Bean 实例(开发者无需干预)
public UserBean() {
System.out.println("【阶段1】实例化 Bean:调用无参构造器");
}
// ------------------- 阶段2:设置 Bean 属性(依赖注入) -------------------
// Spring 自动为属性赋值(setter注入/字段注入)
public void setUsername(String username) {
this.username = username;
System.out.println("【阶段2】设置 Bean 属性:username = " + username);
}
// ------------------- 阶段3:BeanNameAware 接口 -------------------
// 注入当前 Bean 在容器中的名称
@Override
public void setBeanName(String name) {
System.out.println("【阶段3】BeanNameAware:Bean 名称 = " + name);
}
// ------------------- 阶段4:BeanFactoryAware 接口 -------------------
// 注入当前 Bean 所属的 BeanFactory
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【阶段4】BeanFactoryAware:BeanFactory = " + beanFactory.getClass().getSimpleName());
}
// ------------------- 阶段5:ApplicationContextAware 接口 -------------------
// 注入 Spring 应用上下文(若依框架中常用此接口获取容器中的 Bean)
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【阶段5】ApplicationContextAware:ApplicationContext = " + applicationContext.getClass().getSimpleName());
}
// ------------------- 阶段6:BeanPostProcessor 前置处理 -------------------
// 需自定义 BeanPostProcessor 实现,见下方代码
// ------------------- 阶段7:初始化(@PostConstruct / InitializingBean) -------------------
// 方式1:@PostConstruct 注解(JSR-250标准,推荐)
@PostConstruct
public void postConstruct() {
System.out.println("【阶段7-1】@PostConstruct:初始化 Bean");
}
// 方式2:实现 InitializingBean 接口
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【阶段7-2】InitializingBean:afterPropertiesSet 方法执行");
}
// 方式3:自定义 init-method(XML/注解配置,见配置类)
public void customInitMethod() {
System.out.println("【阶段7-3】自定义 init-method:初始化逻辑");
}
// ------------------- 阶段8:BeanPostProcessor 后置处理 -------------------
// 需自定义 BeanPostProcessor 实现,见下方代码
// ------------------- 阶段9:Bean 就绪,对外提供服务 -------------------
public void doBusiness() {
System.out.println("【阶段9】Bean 就绪:执行业务逻辑,username = " + username);
}
// ------------------- 阶段10:销毁(@PreDestroy / DisposableBean) -------------------
// 方式1:@PreDestroy 注解(JSR-250标准,推荐)
@PreDestroy
public void preDestroy() {
System.out.println("【阶段10-1】@PreDestroy:销毁前处理");
}
// 方式2:实现 DisposableBean 接口
@Override
public void destroy() throws Exception {
System.out.println("【阶段10-2】DisposableBean:destroy 方法执行");
}
// 方式3:自定义 destroy-method(XML/注解配置,见配置类)
public void customDestroyMethod() {
System.out.println("【阶段10-3】自定义 destroy-method:销毁逻辑");
}
}
|
自定义 BeanPostProcessor(核心扩展点)
BeanPostProcessor 是 Spring 生命周期中最强大的扩展点,可对所有 Bean 进行前置 / 后置处理(若依框架中的权限切面、日志切面底层都依赖类似机制):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 自定义 BeanPostProcessor,拦截所有 Bean 的初始化前后
*/
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
// 初始化前处理(阶段6)
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userBean".equals(beanName)) { // 仅处理指定 Bean
System.out.println("【阶段6】BeanPostProcessor 前置处理:" + beanName);
}
return bean; // 必须返回 Bean 实例,否则会导致 Bean 丢失
}
// 初始化后处理(阶段8)
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("userBean".equals(beanName)) {
System.out.println("【阶段8】BeanPostProcessor 后置处理:" + beanName);
}
return bean;
}
}
|
配置类(注册 Bean + 指定初始化 / 销毁方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanConfig {
@Bean(initMethod = "customInitMethod", destroyMethod = "customDestroyMethod")
public UserBean userBean() {
UserBean userBean = new UserBean();
userBean.setUsername("admin"); // 模拟依赖注入
return userBean;
}
}
|
测试类(触发生命周期)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanLifecycleTest {
public static void main(String[] args) {
// 1. 创建 Spring 容器,加载配置
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
// 2. 获取 Bean 并执行业务逻辑
UserBean userBean = context.getBean(UserBean.class);
userBean.doBusiness();
// 3. 关闭容器,触发 Bean 销毁
context.close();
}
}
|
输出结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
【阶段1】实例化 Bean:调用无参构造器
【阶段2】设置 Bean 属性:username = admin
【阶段3】BeanNameAware:Bean 名称 = userBean
【阶段4】BeanFactoryAware:BeanFactory = DefaultListableBeanFactory
【阶段5】ApplicationContextAware:ApplicationContext = AnnotationConfigApplicationContext
【阶段6】BeanPostProcessor 前置处理:userBean
【阶段7-1】@PostConstruct:初始化 Bean
【阶段7-2】InitializingBean:afterPropertiesSet 方法执行
【阶段7-3】自定义 init-method:初始化逻辑
【阶段8】BeanPostProcessor 后置处理:userBean
【阶段9】Bean 就绪:执行业务逻辑,username = admin
【阶段10-1】@PreDestroy:销毁前处理
【阶段10-2】DisposableBean:destroy 方法执行
【阶段10-3】自定义 destroy-method:销毁逻辑
|
关键补充(结合实际开发)
不同初始化 / 销毁方式的优先级
-
初始化优先级:@PostConstruct > InitializingBean.afterPropertiesSet() > 自定义 init-method
-
销毁优先级:@PreDestroy > DisposableBean.destroy() > 自定义 destroy-method
-
推荐使用 @PostConstruct 和 @PreDestroy(解耦 Spring 接口,符合开闭原则)。
原型 Bean 的生命周期差异
-
原型 Bean 由容器创建实例、注入属性、执行初始化,但不管理销毁阶段(容器关闭时不会调用 destroy 方法);
-
若需销毁原型 Bean,需手动调用销毁方法。
若依框架中的生命周期应用
-
ApplicationContextAware:若依框架中的 SpringUtils 工具类实现此接口,用于手动获取容器中的 Bean,解决循环依赖;
-
@PostConstruct:若依的定时任务、缓存初始化等逻辑,常放在 @PostConstruct 方法中,确保 Bean 初始化完成后执行;
-
BeanPostProcessor:若依的权限注解解析、数据权限切面等,底层依赖 BeanPostProcessor 扩展。
核心原理(为什么能控制生命周期?)
Spring 容器通过 BeanFactory(核心是 DefaultListableBeanFactory)管理 Bean 生命周期:
实例化:通过反射创建 Bean 实例(AbstractAutowireCapableBeanFactory.createBeanInstance);
属性填充:解析依赖,注入属性(populateBean);
初始化:执行各类初始化方法(initializeBean);
销毁:容器关闭时,遍历单例 Bean 执行销毁方法(destroySingletons)。
总结
核心流程:Spring Bean 生命周期可概括为「实例化 → 属性注入 → 感知容器 → 前置处理 → 初始化 → 后置处理 → 就绪使用 → 销毁」8 个核心阶段;
扩展方式:常用 @PostConstruct/@PreDestroy 做初始化 / 销毁,BeanPostProcessor 做全局 Bean 增强,ApplicationContextAware 手动获取容器;
实战要点:若依框架中大量使用 ApplicationContextAware 和 @PostConstruct,掌握这些扩展点能灵活定制 Bean 行为。
理解 Bean 生命周期,能帮你解决「Bean 初始化时机不对」「依赖注入失败」「销毁资源未释放」等实际开发问题,也是深入学习 Spring 核心原理的基础