一、生命周期基础认知
1. 什么是生命周期
何谓生命周期?它本质是对象从创建到销毁的完整过程,期间会按既定规则执行一系列固定操作,同时允许插入自定义逻辑影响流程。举个生活化的例子:一个人一天的生活就是他当天的生命周期 —— 从起床→洗漱→吃饭→上班→下班→睡觉,每个环节是固定流程,构成了完整的 “生命周期链路”。
对于程序中的对象而言,生命周期同样是 “从初始化到销毁” 的闭环:比如普通 Java 对象的new创建→属性赋值→方法调用→垃圾回收,而 Spring Bean 作为被 Spring 容器管理的特殊对象,其生命周期被容器严格管控,流程更规范、可扩展更强。

2. 生命周期中的 “可扩展点”
生命周期的核心价值不仅在于固定流程,更在于支持 “插入自定义逻辑”—— 就像生活中固定流程之外的 “意外情况”:起床和吃饭之间,妈妈可能让你先洗手;上班前,朋友可能用 “克隆体” 代替你。这些 “额外操作” 不改变核心流程,但能影响最终结果,这就是生命周期的 “可扩展点”。 用代码模拟这一逻辑(原代码补充说明):
import com.google.common.collect.Lists;
import java.util.List;
/**
* 定义“影响生命周期的处理器接口”——对应Spring中的扩展接口
*/
public interface IProcessNi {
// 吃饭前的扩展操作(对应Bean初始化前的处理)
void beforeChifan(Ni ni);
// 上班前的扩展操作(对应Bean实例化后的替换/修改)
Ni beforeShangban(Ni ni);
}
/**
* 核心对象“你”——对应Spring中的Bean
*/
public class Ni {
// 核心方法:吃饭(对应Bean的业务方法)
public void chifan() {
System.out.println("开始吃饭");
}
// 核心方法:上班(对应Bean的业务方法)
public void shangban() {
System.out.println("开始上班");
}
// 自定义操作:洗手(对应Bean的自定义初始化逻辑)
public void xishou() {
System.out.println("手已干净");
}
/**
* 扩展处理器1:妈妈——对应Spring中的BeanPostProcessor实现类
* 作用:在核心流程前添加固定逻辑(洗手)
*/
public static class Mama implements IProcessNi {
@Override
public void beforeChifan(Ni ni) {
ni.xishou(); // 吃饭前强制洗手(固定扩展逻辑)
}
@Override
public Ni beforeShangban(Ni ni) {
return ni; // 不修改核心对象,仅放行
}
}
/**
* 扩展处理器2:朋友——对应Spring中的InstantiationAwareBeanPostProcessor
* 作用:在核心流程前替换核心对象(克隆体)
*/
public static class Pengyou implements IProcessNi {
@Override
public void beforeChifan(Ni ni) {
ni.xishou(); // 继承基础扩展逻辑
}
@Override
public Ni beforeShangban(Ni ni) {
return new Ni(); // 替换核心对象(克隆体上班)
}
}
// 模拟生命周期执行流程(对应Spring容器管理Bean的过程)
public static void main(String[] args) {
// 1. 收集所有扩展处理器(对应Spring容器扫描BeanPostProcessor)
List processors = Lists.newArrayList(new Mama(), new Pengyou());
// 2. 创建核心对象(对应Bean实例化)
Ni ni = new Ni();
// 3. 执行“吃饭前”扩展逻辑(对应Bean初始化前处理)
for (IProcessNi processor : processors) {
processor.beforeChifan(ni);
}
// 4. 执行核心方法(对应Bean的业务逻辑调用)
ni.chifan();
// 5. 执行“上班前”扩展逻辑(对应Bean实例化后处理)
for (IProcessNi processor : processors) {
Ni newNi = processor.beforeShangban(ni);
if (newNi != null) {
ni = newNi; // 替换核心对象(对应Bean实例替换)
break;
}
}
// 6. 执行核心方法(对应Bean的业务逻辑调用)
ni.shangban();
// 注:实际Spring中还会有“销毁”阶段(对应ni的资源释放)
}
}
代码核心意义:通过IProcessNi接口定义 “扩展点”,Mama和Pengyou作为扩展实现,模拟了 Spring 中 “处理器接口” 的作用 —— 不修改 Bean 核心逻辑,却能通过 “前置处理”“对象替换” 影响生命周期,这正是 Spring Bean 生命周期可扩展性的设计核心。
二、Spring Bean 的生命周期核心定义
1. 什么是 Spring Bean 的生命周期
Spring Bean 的生命周期,是指Bean 从被 Spring 容器创建、初始化、使用到最终销毁的完整过程。与普通 Java 对象不同,Bean 的整个生命周期由 Spring IoC 容器全程管理,核心特点是:
- 流程标准化:所有 Bean 遵循统一的生命周期链路;
- 扩展点丰富:允许通过特定接口或注解插入自定义逻辑;
- 资源自动化:容器负责 Bean 的依赖注入、初始化和销毁资源释放。 其核心生命周期链路可概括为:类型预测→构造函数选择→实例化(创建对象)→Bean 定义合并→循环依赖处理→依赖注入(设置属性)→初始化(自定义逻辑)→就绪(供应用调用)→销毁(资源释放)。
2. 影响 Bean 生命周期的核心接口
Spring 通过一系列 “处理器接口” 允许开发者干预 Bean 生命周期:
| 接口类名 | 核心作用 | 关键方法 | 执行时机 | 典型应用场景 |
|---|---|---|---|---|
InstantiationAwareBeanPostProcessor | 影响 Bean 实例化、依赖注入阶段 | predictBeanType() | Bean 实例化前,预测 Bean 的最终类型 | 类型校验、动态类型推断(如泛型 Bean 类型解析) |
determineCandidateConstructors() | 实例化前,Bean 有多个构造函数时执行 | 构造函数选择(如 @Autowired 标注的多构造函数筛选) | ||
postProcessBeforeInstantiation() | Bean 实例化(new 对象)之前 | 动态代理对象创建、Bean 实例替换 | ||
postProcessAfterInstantiation() | Bean 实例化之后,依赖注入之前 | 检查 Bean 属性合法性、阻止依赖注入(返回 false 时) | ||
postProcessProperties() | 依赖注入过程中(设置 Bean 属性时) | 动态修改 Bean 属性值、属性校验(如加密属性解密) | ||
BeanPostProcessor | 影响 Bean 初始化阶段 | postProcessBeforeInitialization() | Bean 初始化方法(如init-method)之前 | AOP 代理织入、属性增强、日志打印 |
postProcessAfterInitialization() | Bean 初始化方法之后 | 事务代理创建、Shiro 过滤器初始化、自定义 Bean 包装 | ||
MergedBeanDefinitionPostProcessor | Bean 定义合并后处理 | postProcessMergedBeanDefinition() | Bean 实例化后,依赖注入前,BeanDefinition 合并完成后 | 缓存 Bean 元数据(如 @Autowired 标注的字段信息)、不修改 Bean 定义仅读取 |
SmartInstantiationAwareBeanPostProcessor | 循环依赖处理、提前暴露 Bean | getEarlyBeanReference() | 依赖注入阶段,处理循环依赖时提前暴露 Bean 引用 | 循环依赖场景下的代理对象提前暴露(如 AOP 代理的循环依赖处理) |
DestructionAwareBeanPostProcessor | 影响 Bean 销毁阶段 | postProcessBeforeDestruction() | 容器关闭时,Bean 销毁方法执行前 | 销毁前资源清理(如缓存清理、连接池预热关闭) |
| 关键说明: |
SmartInstantiationAwareBeanPostProcessor是InstantiationAwareBeanPostProcessor的子接口,专注于循环依赖处理和 Bean 类型预测;MergedBeanDefinitionPostProcessor的核心是 “读取 Bean 定义元数据”,禁止修改 BeanDefinition(否则可能导致容器初始化异常);DestructionAwareBeanPostProcessor是BeanPostProcessor的子接口,专门处理销毁阶段的扩展逻辑,比DisposableBean的执行时机更早。
三、Spring Bean 生命周期详细调用流程
按执行顺序拆解 Bean 从创建到销毁的完整步骤:
flowchart TD
A["1. 容器启动与Bean定义加载"] -->|"扫描@Configuration/@Bean/XML,生成BeanDefinition"| B["2. Bean实例化(Instantiation)"]
B -->B1["InstantiationAwareBeanPostProcessor.predictBeanType()"]
B1-->
C["InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()"]
C -->|"返回非空实例?"| D{判断}
D -->|是| S1["BeanPostProcessor.postProcessAfterInitialization()"]
S1-->|"返回非空实例?"| D1{判断}
D1-->|是|T
D1-->|否|F["InstantiationAwareBeanPostProcessor.determineCandidateConstructors"]
D -->|否| F
F-->F1["创建实例"]
F1-->F2["MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()"]
F2 --> E["执行InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()"]
E -->|"返回false?"| E1{判断}
E1-->|是|J
E1-->|否|G["3. 依赖注入(Dependency Injection)"]
G -->H["InstantiationAwareBeanPostProcessor.postProcessProperties()"]
H -->|"动态修改属性/属性校验"| I["容器注入@Autowired/@Resource依赖"]
I --> J["4. 初始化前准备"]
J -->|"检查Aware接口并回调"| K["BeanNameAware.setBeanName()"]
K --> L["BeanFactoryAware.setBeanFactory()"]
L --> M["ApplicationContextAware.setApplicationContext()"]
M --> N["5. Bean初始化(Initialization)"]
N -->|" 按@Order执行"| O["BeanPostProcessor.postProcessBeforeInitialization()"]
O -->|"AOP代理织入/属性增强"| P["执行自定义初始化方法"]
P --> Q["InitializingBean.afterPropertiesSet()"]
Q --> R["@Bean(initMethod)/XML init-method"]
R -->|"按@Order执行"| S["BeanPostProcessor.postProcessAfterInitialization()"]
S -->|"事务代理/Shiro初始化/最终代理"| T["6. Bean就绪与使用"]
T -->|"存入单例池,供应用getBean()调用"| U["应用调用Bean业务方法"]
U --> V["7. Bean销毁(Destruction)"]
V -->|"容器关闭触发"| W["@PreDestroy注解方法"]
W --> X["DisposableBean.destroy()"]
X --> Y["@Bean(destroyMethod)/XML destroy-method"]
Y --> Z["释放资源(连接池/文件流/定时任务)"]
%% 样式标注
classDef stage fill:#f0f8ff,stroke:#4169e1,stroke-width:2px
classDef extendPoint fill:#f8f8ff,stroke:#ff6347,stroke-width:2px
classDef customMethod fill:#f5fafe,stroke:#32cd32,stroke-width:2px
class A,B,G,J,N,T,V stage
class C,E,H,O,S extendPoint
class Q,R,W,X,Y customMethod
1. 容器启动与 Bean 定义加载
- Spring 容器(如
ApplicationContext)启动时,会扫描配置类(@Configuration)或 XML 配置,加载所有@Bean注解或定义的Bean信息,存储在BeanDefinition` 中(包含 Bean 的类名、属性、依赖、初始化方法等元数据); - 若存在父子 Bean 定义(如通过
parent属性指定),容器会先合并 BeanDefinition,形成最终的RootBeanDefinition。
2. Bean 类型预测与实例化前调用
- 扩展点 1:执行
InstantiationAwareBeanPostProcessor.predictBeanType()—— 预测 Bean 的最终类型,容器可根据预测结果进行类型匹配(如依赖注入时的类型校验),若返回null则使用 BeanDefinition 中配置的类型; - 扩展点 2:执行
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()—— 可在此返回自定义实例(如动态代理对象),若返回非空实例,将跳过后续默认实例化流程,直接进入实例化后处理; - 若上一步返回
null,容器通过反射执行筛选后的构造函数,创建 Bean 的 “空对象”(属性未赋值);
3. Bean 实例化(Instantiation)
-
扩展点 3:执行
InstantiationAwareBeanPostProcessor.determineCandidateConstructors()—— 当 Bean 存在多个构造函数(如无参构造、带参构造)时,容器通过该方法筛选候选构造函数(如优先选择@Autowired标注的构造函数),若返回null则使用默认无参构造函数。 -
扩展点 4:执行
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()——BeanDefinition 合并完成后执行,用于读取 Bean 的元数据(如@Autowired标注的字段、@Value注解的属性)并缓存,禁止修改 BeanDefinition 的核心配置(如类名、构造函数),否则会导致依赖注入异常。
4. 循环依赖处理(提前暴露 Bean)
- 若 Bean 存在循环依赖(如 A 依赖 B,B 依赖 A),且 Bean 为单例模式,容器会通过 “三级缓存” 机制处理:
- 实例化后,容器将 Bean 的原始实例存入 “三级缓存”(
singletonFactories); - 当其他 Bean 依赖当前 Bean 时,执行
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference()—— 提前暴露 Bean 的引用(若需 AOP 代理,此时会生成代理对象),存入 “二级缓存”(earlySingletonObjects); - 当前 Bean 完成初始化后,将最终实例存入 “一级缓存”(
singletonObjects),并移除二级、三级缓存中的引用;
- 该扩展点的核心作用是在 Bean 未完成初始化前,提前提供可用引用,解决循环依赖问题。
5. 依赖注入(Dependency Injection)
- 扩展点 5:执行
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()—— 返回boolean类型,若返回false,容器将终止后续的属性注入流程(适用于无需注入属性的 Bean); - 若上一步返回
true,扩展点 6:执行InstantiationAwareBeanPostProcessor.postProcessProperties()—— 动态修改属性值(如解密配置文件中的敏感信息)、添加额外属性或校验属性合法性; - 容器根据 Bean 的依赖关系(如
@Autowired、@Resource、XML 配置的property),将依赖的 Bean 注入到当前 Bean 的属性中,完成属性赋值。
6. 初始化前准备
- 检查 Bean 是否实现了
Aware系列接口(如BeanNameAware、BeanFactoryAware、ApplicationContextAware),并按顺序调用对应方法:
BeanNameAware.setBeanName():传入 Bean 在容器中的唯一名称;BeanFactoryAware.setBeanFactory():传入当前 BeanFactory 实例,允许 Bean 手动获取其他 Bean;ApplicationContextAware.setApplicationContext():传入当前 ApplicationContext 实例,可访问容器的环境变量、资源文件等;
- 这些接口的作用是让 Bean “感知” 容器上下文信息,满足自定义逻辑对容器资源的依赖。
7. Bean 初始化(Initialization)
- 扩展点 7:执行
BeanPostProcessor.postProcessBeforeInitialization()—— 所有BeanPostProcessor按@Order注解指定的顺序执行,可在此对 Bean 进行前置增强(如 AOP 代理织入、日志拦截器添加),返回处理后的 Bean 实例; - 执行自定义初始化方法(按以下顺序):
- 执行
@PostConstruct注解标记的方法(JSR-250 规范注解,容器通过CommonAnnotationBeanPostProcessor识别); - 若 Bean 实现了
InitializingBean接口,调用afterPropertiesSet()方法; - 若在 BeanDefinition 中指定了
init-method(XML 配置)或@Bean(initMethod = "xxx"),执行对应的自定义初始化方法;
- 扩展点 8:执行
BeanPostProcessor.postProcessAfterInitialization()——Bean 初始化的最后一个扩展点,对 Bean 进行最终增强(如事务代理创建、Shiro 过滤器链初始化),返回的实例将作为 “成熟 Bean” 存入容器。
8. Bean 就绪与使用
- 成熟 Bean 存入 Spring 容器的单例池(
singletonObjects,默认单例模式),此时 Bean 已完全可用; - 应用程序可通过
ApplicationContext.getBean()、依赖注入(@Autowired)等方式获取 Bean,调用其业务方法; - 原型 Bean(
@Scope("prototype")):容器仅完成上述 1-7 步骤,之后不再管理 Bean 的生命周期,每次getBean()都会创建新实例,使用后由 JVM 垃圾回收。
9. Bean 销毁(Destruction)
- 当 Spring 容器关闭时(如应用停止、
ApplicationContext.close()调用),触发 Bean 的销毁流程:
- 扩展点 9:执行
DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()—— 销毁前的前置处理(如清理缓存、关闭临时连接),所有实现类按顺序执行; - 执行
@PreDestroy注解标记的方法(JSR-250 规范注解,由CommonAnnotationBeanPostProcessor处理); - 若 Bean 实现 DisposableBean 接口,调用destroy()方法
- 在 @Bean(destroyMethod = "shutdown") 中指定销毁方法
四、关键补充说明
1. 单例 Bean 与原型 Bean 的生命周期差异:
- 单例 Bean(默认):生命周期与 Spring 容器一致 —— 容器启动时创建,容器关闭时销毁;
- 原型 Bean(
@Scope("prototype")):容器仅负责实例化和依赖注入,之后不再管理 —— 每次getBean()都会创建新实例,使用后由 JVM 垃圾回收,销毁方法(destroy-method)不会被容器调用。
2. 注解方式简化生命周期操作:
- 无需实现
InitializingBean和DisposableBean,可直接用@PostConstruct(初始化方法)和@PreDestroy(销毁方法)注解标记普通方法,Spring 会自动识别执行。
3. 扩展点的执行顺序:
- 多个
BeanPostProcessor实现类可通过@Order注解指定执行顺序(数值越小越先执行); InstantiationAwareBeanPostProcessor的方法执行早于BeanPostProcessor的方法。