Spring Bean 生命周期完整揭秘:从实例化到销毁的全过程
Spring Bean 生命周期完整揭秘:从实例化到销毁的全过程
后端技术源码解读系列 · 第二篇
基于 Spring Framework 6.1.5 源码,逐行剖析 Bean 从创建到销毁的完整生命周期。读完本文,你将掌握 Spring 容器管理 Bean 的底层真相。
一、前言:为什么你必须理解 Bean 生命周期
在日常开发中,我们习惯了使用 @Component、@Service、@Autowired 等注解,让 Spring 自动管理我们的对象。但你有没有想过:
- 一个 Bean 从被扫描到最终可以使用,中间经历了哪些步骤?
@PostConstruct和@PreDestroy注解是在什么时候被调用的?InitializingBean和BeanPostProcessor有什么区别?为什么会有两个初始化回调接口?- 循环依赖是如何被 Spring 检测和解决的?
- Bean 的销毁过程是怎样的?容器关闭时如何确保资源被正确释放?
答案全部藏在 Bean 的生命周期里。 理解这个生命周期,你才能真正掌握 Spring 的设计哲学,才能在遇到复杂问题时快速定位根源。
今天,本座带你把 Spring Bean 的完整生命周期彻底拆开,从源码层面看透每一个关键节点。
二、生命周期全景图:上帝视角的完整流程
在深入细节之前,我们先从宏观上认识一下 Bean 生命周期的完整流程。这将帮助我们建立整体的认知框架。
2.1 完整生命周期流程图
2.2 核心阶段分类
Spring Bean 的生命周期可以划分为 4 大阶段,共 15+ 个关键节点:
| 阶段 | 核心职责 | 关键节点 | 影响范围 |
|---|---|---|---|
| 实例化阶段 | 创建 Bean 对象本身 | 构造器调用、工厂方法、实例化后置处理器 | 所有 Bean |
| 属性填充阶段 | 注入依赖 | @Autowired 处理、byType/byName 注入、SpEL 表达式求值 | 依赖注入 Bean |
| 初始化阶段 | 完成初始化逻辑 | Aware 接口、BeanPostProcessor、InitializingBean、init-method | 需要初始化的 Bean |
| 销毁阶段 | 释放资源 | @PreDestroy、DisposableBean、destroy-method | 需要清理的 Bean |
2.3 生命周期回调机制对比
Spring 提供了多种方式来介入 Bean 的生命周期,不同方式有不同的适用场景:
| 回调类型 | 接口/注解 | 执行时机 | 优先级 | 推荐场景 |
|---|---|---|---|---|
| 构造器回调 | 构造函数 | 实例化时 | 最高 | 基本属性初始化 |
| Aware 接口 | BeanNameAware 等 | 属性填充后 | 高 | 需要访问 Spring 容器信息 |
| JSR-250 注解 | @PostConstruct/@PreDestroy | 初始化/销毁阶段 | 中 | 标准化生命周期回调 |
| 生命周期接口 | InitializingBean/DisposableBean | 初始化/销毁阶段 | 中 | 需要 Spring 特定功能的场景 |
| 自定义方法 | init-method/destroy-method | 初始化/销毁阶段 | 低 | 遗留系统集成或解耦 Spring |
| 后置处理器 | BeanPostProcessor | 初始化前后 | 可编程控制 | 框架级扩展、AOP 代理 |
本座建议: 优先使用 @PostConstruct 和 @PreDestroy 注解,这是 Java 标准化的方式,代码侵入性最小。只有需要访问 Spring 特定功能时才考虑 Aware 接口。
三、实例化阶段:Bean 对象的诞生
实例化是 Bean 生命的起点,Spring 需要根据 BeanDefinition 创建出真正的对象实例。
3.1 实例化的核心入口
实例化的核心逻辑在 AbstractAutowireCapableBeanFactory.createBean() 方法中(Spring Framework 6.1.5):
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 行号:503-528
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 🔍 1. 解析 Bean 的实际类型(处理动态代理等场景)
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 🔍 2. 准备方法覆盖(lookup-method、replace-method)
mbdToUse.prepareMethodOverrides();
try {
// 🔍 3. 给 InstantiationAwareBeanPostProcessor 一个机会返回代理对象
// 这就是 @EnableAspectJAutoProxy 能在此返回代理对象的原因
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean; // 如果后置处理器返回了对象,直接跳过后续实例化流程
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 🔍 4. 执行真正的实例化逻辑
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
逐行解析:
- Line 508:
resolveBeanClass- 动态加载 Bean 的 Class 对象,支持类加载器隔离场景 - Line 511:
prepareMethodOverrides- 处理<lookup-method>和<replace-method>配置 - Line 514-519:
resolveBeforeInstantiation- 关键点! 这是 AOP 代理的入口,AbstractAutoProxyCreator在此返回代理对象,跳过普通实例化 - Line 524:
doCreateBean- 如果没有代理对象,执行常规实例化流程
3.2 实例化的三种方式
Spring 支持多种实例化策略,通过 InstantiationStrategy 接口抽象:
3.2.1 策略对比表
| 实例化方式 | 配置方式 | 适用场景 | 性能 | 灵活性 |
|---|---|---|---|---|
| 构造器实例化 | <bean class="com.Xxx"> 或 @Component |
标准场景,POJO 对象 | ⭐⭐⭐⭐ | ⭐⭐ |
| 静态工厂方法 | factory-method="newInstance" |
遗留系统整合、单例模式 | ⭐⭐⭐ | ⭐⭐⭐ |
| 实例工厂方法 | factory-bean + factory-method |
复杂对象构建、依赖上下文 | ⭐⭐ | ⭐⭐⭐⭐ |
| Supplier 回调 | 编程式注册 registerBean |
函数式编程、动态 Bean | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
3.2.2 构造器实例化源码
// org.springframework.beans.factory.support.SimpleInstantiationStrategy
// 行号:78-95
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 🔍 1. 如果没有方法覆盖,使用 JVM 原生反射(性能最优)
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 使用反射获取构造器(支持自动装配)
constructorToUse = bd.getClazz().getDeclaredConstructor();
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
}
// 使用反射 API 创建实例
return BeanUtils.instantiateClass(constructorToUse);
} else {
// 🔍 2. 有方法覆盖时,使用 CGLIB 子类化
// 原因:需要在子类中重写方法以实现 lookup-method 功能
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
关键点:
- Line 85:使用
synchronized确保构造器解析的线程安全(Spring 大部分操作无锁,此处是个例外) - Line 93:
instantiateWithMethodInjection- CGLIB 动态子类,性能开销约 5-10 倍
3.3 实例化后置处理器:InstantiationAwareBeanPostProcessor
在实例化之前,Spring 给了最后一次"拦截"机会:
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 行号:976-999
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor ibpp) {
Object result = ibpp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
// 🔍 如果返回了非 null 对象,直接跳过后续实例化和初始化流程
return result;
}
}
}
return null;
}
应用场景:
- AOP 代理提前创建:
AbstractAutoProxyCreator在此返回代理对象,避免目标对象被创建 - 循环依赖解决:
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference暴露早期引用 - 配置类增强:
ConfigurationClassPostProcessor确保@Configuration类的方法调用被拦截
四、属性填充阶段:依赖注入的核心环节
实例化完成后,Bean 对象还是一张"白纸",属性都是默认值。属性填充阶段负责把依赖注入进来。
4.1 属性填充的核心流程
4.2 populateBean 源码逐行解析
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 行号:1425-1491
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 🔍 1. 实例化但属性未填充的 Bean(用于提前暴露引用解决循环依赖)
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
// 没有可填充的属性,直接返回
return;
}
// 🔍 2. 给 InstantiationAwareBeanPostProcessor 一个机会修改属性
// 这一步会处理 @Autowired 注解,完成依赖注入
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessors()) {
PropertyValues pvsToUse = bp.postProcessProperties(((ConfigurableListableBeanFactory) this), bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
// 🔍 如果返回 null,表示后续处理器不应继续执行
return;
}
}
}
// 🔍 3. 处理 XML 配置的 <property> 标签或 @Value 注解
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
// 🔍 4. 自动装配模式(byType/byName)
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称自动装配
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型自动装配
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 🔍 5. 应用属性值到 Bean 实例
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
逐行解析:
- Line 1430-1437:检查
BeanWrapper是否为 null(针对静态工厂方法场景) - Line 1443-1450:核心点! 调用
InstantiationAwareBeanPostProcessor.postProcessProperties,AutowiredAnnotationBeanPostProcessor在此处理@Autowired和@Value - Line 1455-1470:处理传统 XML 的自动装配模式(
autowire="byName/byType") - Line 1473-1475:
applyPropertyValues- 使用反射将属性值设置到 Bean 实例
4.3 依赖注入的三种方式对比
| 注入方式 | 实现机制 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|
| 字段注入 | @Autowired 在字段上 |
代码简洁 | 不利于单元测试、无法使用 final | 快速原型、简单场景 |
| Setter 注入 | @Autowired 在 setter 上 |
灵活、可选依赖 | 无法保证不可变性 | 可选依赖、多属性注入 |
| 构造器注入 | @Autowired 在构造器上 |
不可变性、强制依赖、易测试 | 构造器参数过多时笨重 | 推荐作为默认选择 |
4.4 循环依赖的解决机制
Spring 使用三级缓存解决循环依赖问题:
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
// 三级缓存定义
/** 一级缓存:完整的 Bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 二级缓存:提前暴露的 Bean(未完全初始化) */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** 三级缓存:Bean 工厂(可生成代理对象) */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
循环依赖解决流程:
关键点:
- 三级缓存的工厂:
getEarlyBeanReference方法会调用SmartInstantiationAwareBeanPostProcessor,给 AOP 代理一个机会提前暴露 - 为什么需要三级缓存:如果 Bean 不需要 AOP 代理,二级缓存就够;但如果需要代理,必须通过工厂方法动态生成代理对象
五、初始化阶段:完成 Bean 的准备工作
初始化阶段是 Bean "成年"前的最后准备,包括执行 Aware 接口回调、初始化回调方法、以及 BeanPostProcessor 的增强处理。
5.1 初始化阶段的完整流程
5.2 Aware 接口回调源码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 行号:1738-1751
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// 🔍 1. BeanNameAware:获取 Bean 在容器中的名字
if (bean instanceof BeanNameAware aware) {
aware.setBeanName(beanName);
}
// 🔍 2. BeanClassLoaderAware:获取类加载器
if (bean instanceof BeanClassLoaderAware aware) {
aware.setBeanClassLoader(getBeanClassLoader());
}
// 🔍 3. BeanFactoryAware:获取 BeanFactory 引用
if (bean instanceof BeanFactoryAware aware) {
aware.setBeanFactory(this);
}
}
}
注意事项:
- 执行时机:在属性填充之后、初始化回调之前
- 设计意图:让 Bean 能够访问 Spring 容器的基础设施
- 最佳实践:谨慎使用
BeanFactoryAware,会让代码与 Spring 强耦合
5.3 初始化回调的三种方式
Spring 提供了三种初始化回调方式,执行顺序如下:
5.3.1 @PostConstruct 注解
// org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
// 行号:110-132
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 🔍 1. 查找生命周期元数据(解析 @PostConstruct 和 @PreDestroy)
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
// 🔍 2. 调用所有初始化方法
try {
metadata.invokeInitMethods(bean, beanName);
} catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
return bean;
}
// 内部方法:执行 @PostConstruct 标注的方法
private void invokeInitMethods(Object target) throws Throwable {
for (LifecycleMethod method : this.initMethods) {
// 🔍 使用反射调用初始化方法
method.method.invoke(target);
}
}
特点:
- 来源:JSR-250 规范,Java 标准化注解
- 执行时机:最早执行
- 推荐度:⭐⭐⭐⭐⭐(首选)
5.3.2 InitializingBean 接口
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 行号:1766-1777
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
// 🔍 1. 判断 Bean 是否实现了 InitializingBean 接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
// 🔍 2. 调用 afterPropertiesSet 方法
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 🔍 3. 调用自定义的 init-method
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasText(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 使用反射调用自定义初始化方法
invokeCustomInitMethod(bean, initMethodName);
}
}
}
逐行解析:
- Line 1770:检查 Bean 是否实现了
InitializingBean接口 - Line 1775:调用
afterPropertiesSet()方法(Spring 生命周期接口) - Line 1790-1797:调用 XML 配置或注解中的
init-method
5.3.3 三种初始化方式对比
| 方式 | 执行顺序 | 类型耦合 | 推荐度 | 典型场景 |
|---|---|---|---|---|
| @PostConstruct | 1 | 低(JSR-250) | ⭐⭐⭐⭐⭐ | 标准化初始化逻辑 |
| InitializingBean | 2 | 高(Spring 接口) | ⭐⭐⭐ | 需要 Spring 特定功能 |
| init-method | 3 | 低(配置驱动) | ⭐⭐⭐⭐ | 遗留系统集成、解耦 Spring |
5.4 BeanPostProcessor:最强大的扩展点
BeanPostProcessor 是 Spring 提供的最强大的扩展机制之一,它允许在初始化前后对 Bean 进行增强。
5.4.1 源码解析
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 行号:1107-1125
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
// 🔍 如果返回 null,中断后续处理器执行
return result;
}
result = current;
}
return result;
}
// 行号:1135-1153
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
// 🔍 如果返回 null,中断后续处理器执行
return result;
}
result = current;
}
return result;
}
5.4.2 常见的 BeanPostProcessor 实现
| BeanPostProcessor | 功能 | 典型应用场景 |
|---|---|---|
| AutowiredAnnotationBeanPostProcessor | 处理 @Autowired、@Value 注解 |
依赖注入 |
| CommonAnnotationBeanPostProcessor | 处理 JSR-250 注解(@Resource、@PostConstruct) |
Java EE 资源注入 |
| ApplicationContextAwareProcessor | 处理 ApplicationContextAware 等接口 |
注入 Spring 上下文 |
| AbstractAutoProxyCreator | 创建 AOP 代理 | 声明式事务、AOP 切面 |
| AsyncAnnotationBeanPostProcessor | 处理 @Async 注解 |
异步方法调用 |
| ScheduledAnnotationBeanPostProcessor | 处理 @Scheduled 注解 |
定时任务调度 |
| PersistenceExceptionTranslationPostProcessor | 异常转换 | JPA 异常转 Spring 异常 |
5.4.3 实战:自定义 BeanPostProcessor
/**
* 自定义 BeanPostProcessor 示例:为所有 Controller 添加日志拦截
*/
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(LoggingBeanPostProcessor.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 🔍 在初始化前记录日志
if (bean.getClass().isAnnotationPresent(RestController.class)) {
logger.info("🚀 准备初始化 Controller: {} ({})", beanName, bean.getClass().getSimpleName());
}
return bean; // 返回原 Bean,不做修改
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 🔍 在初始化后为 Controller 创建动态代理
if (bean.getClass().isAnnotationPresent(RestController.class)) {
logger.info("✅ Controller 初始化完成: {}", beanName);
// 返回代理对象,添加方法调用日志
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
logger.info("📞 调用方法: {}.{}", beanName, method.getName());
long start = System.currentTimeMillis();
try {
Object result = method.invoke(bean, args);
logger.info("✓ 方法执行成功,耗时: {}ms", System.currentTimeMillis() - start);
return result;
} catch (Exception e) {
logger.error("✗ 方法执行失败: {}", e.getMessage());
throw e;
}
}
);
}
return bean;
}
}
六、销毁阶段:优雅地释放资源
当 Spring 容器关闭时,需要确保 Bean 的资源被正确释放。销毁阶段提供了多种回调机制。
6.1 销毁流程图
6.2 销毁回调源码解析
// org.springframework.beans.factory.support.DisposableBeanAdapter
// 行号:174-247
@Override
public void destroy() {
// 🔍 1. 执行 @PreDestroy 注解的方法
if (this.invokeDisposableBean) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
} else {
((DisposableBean) this.bean).destroy();
}
}
// 🔍 2. 执行自定义的 destroy-method
if (this.destroyMethod != null) {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
ReflectionUtils.makeAccessible(this.destroyMethod);
this.destroyMethod.invoke(this.bean);
return null;
}, this.acc);
} else {
ReflectionUtils.makeAccessible(this.destroyMethod);
this.destroyMethod.invoke(this.bean);
}
} catch (InvocationTargetException ex) {
String msg = "Destroy method on bean with name '" + this.beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
} else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
}
}
6.3 三种销毁方式对比
| 方式 | 执行顺序 | 推荐度 | 典型场景 |
|---|---|---|---|
| @PreDestroy | 1 | ⭐⭐⭐⭐⭐ | 关闭数据库连接、线程池、释放文件句柄 |
| DisposableBean | 2 | ⭐⭐⭐ | 需要 Spring 特定功能的清理逻辑 |
| destroy-method | 3 | ⭐⭐⭐⭐ | 遗留系统集成、配置驱动的资源释放 |
6.4 实战:优雅地释放资源
/**
* 正确的资源释放示例
*/
@Component
public class ConnectionManager implements DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(ConnectionManager.class);
private ExecutorService executorService;
private DataSource dataSource;
@PostConstruct
public void init() {
// 🔍 初始化时创建资源
executorService = Executors.newFixedThreadPool(10);
logger.info("✅ 线程池已创建");
}
@PreDestroy
public void cleanup() {
// 🔍 优先使用 @PreDestroy 释放资源
logger.info("🔥 开始清理资源...");
if (executorService != null) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
logger.info("✅ 线程池已关闭");
}
}
@Override
public void destroy() throws Exception {
// 🔍 DisposableBean.destroy 作为备用清理逻辑
logger.info("🧹 执行 Spring 销毁回调");
}
}
七、完整生命周期演示:实战示例
让我们通过一个完整的示例,演示 Bean 生命周期的所有关键节点。
7.1 演示 Bean
/**
* 完整生命周期演示 Bean
*/
@Component
@Scope("prototype") // 使用原型模式,每次 getBean 都创建新实例
public class LifecycleDemoBean
implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(LifecycleDemoBean.class);
private String beanName;
private BeanFactory beanFactory;
// 🔍 阶段 1:构造器(实例化阶段)
public LifecycleDemoBean() {
logger.info("1️⃣ 构造器调用 - Bean 实例化");
}
// 🔍 阶段 2:Aware 接口回调(属性填充后)
@Override
public void setBeanName(String name) {
this.beanName = name;
logger.info("2️⃣ BeanNameAware.setBeanName - Bean 名称: {}", name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
logger.info("3️⃣ BeanFactoryAware.setBeanFactory - BeanFactory: {}", beanFactory);
}
// 🔍 阶段 3:@PostConstruct 初始化
@PostConstruct
public void postConstruct() {
logger.info("4️⃣ @PostConstruct - JSR-250 初始化方法");
}
// 🔍 阶段 4:InitializingBean 接口
@Override
public void afterPropertiesSet() throws Exception {
logger.info("5️⃣ InitializingBean.afterPropertiesSet - Spring 初始化接口");
}
// 🔍 阶段 5:自定义 init-method
public void customInitMethod() {
logger.info("6️⃣ 自定义 init-method - 配置驱动的初始化方法");
}
// 🔍 阶段 6:@PreDestroy 销毁
@PreDestroy
public void preDestroy() {
logger.info("7️⃣ @PreDestroy - JSR-250 销毁方法");
}
// 🔍 阶段 7:DisposableBean 接口
@Override
public void destroy() throws Exception {
logger.info("8️⃣ DisposableBean.destroy - Spring 销毁接口");
}
// 🔍 阶段 8:自定义 destroy-method
public void customDestroyMethod() {
logger.info("9️⃣ 自定义 destroy-method - 配置驱动的销毁方法");
}
public void doSomething() {
logger.info("✅ Bean 就绪,可以执行业务逻辑 - BeanName: {}", beanName);
}
}
7.2 配置类
/**
* 生命周期演示配置
*/
@Configuration
@ComponentScan(basePackages = "com.example.lifecycle")
public class LifecycleConfig {
@Bean(initMethod = "customInitMethod", destroyMethod = "customDestroyMethod")
public LifecycleDemoBean lifecycleDemoBean() {
return new LifecycleDemoBean();
}
}
7.3 测试类
/**
* 生命周期测试
*/
public class LifecycleDemo {
public static void main(String[] args) {
// 🔍 1. 创建 Spring 容器
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(LifecycleConfig.class);
System.out.println("\n========== 容器启动完成 ==========\n");
// 🔍 2. 获取 Bean(触发 Bean 的完整生命周期)
LifecycleDemoBean bean
更多推荐

所有评论(0)