Spring Bean生命周期深度解析:从创建到销毁的完整流程
前言
在Spring框架中,Bean的生命周期管理是核心功能之一。理解Bean的生命周期对于编写高质量的Spring应用至关重要。本文将深入探讨Spring Bean的完整生命周期流程,包括关键节点、触发时机以及每个节点的核心代码实现。
一、Bean生命周期整体流程
Spring Bean的生命周期可以分为三个阶段:实例化阶段 、初始化阶段 和销毁阶段。整个流程如下图所示(概念图):
Bean定义加载 → 实例化 → 属性赋值 → Aware接口回调 → BeanPostProcessor前置处理
↓
初始化方法执行 → BeanPostProcessor后置处理 → Bean就绪 → 使用阶段 → 销毁阶段
二、关键生命周期节点详解
1. Bean定义加载(Bean Definition Loading)
在Spring容器启动时,会读取配置文件或注解,创建BeanDefinition对象。
java
// BeanDefinition的创建示例
BeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
beanDefinition.setLazyInit(false);
2. 实例化(Instantiation)
容器通过反射或工厂方法创建Bean实例。
java
// AbstractAutowireCapableBeanFactory中的实例化代码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 判断是否使用工厂方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 使用构造函数实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用默认构造函数
return instantiateBean(beanName, mbd);
}
3. 属性赋值(Population of Properties)
Spring通过依赖注入为Bean设置属性值。
java
// AbstractAutowireCapableBeanFactory中的属性赋值
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// 应用BeanPostProcessors的属性处理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 自动装配属性
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 应用属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
4. Aware接口回调
如果Bean实现了Aware接口,Spring会调用相应的回调方法。
java
// 常见的Aware接口实现
public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("BeanNameAware回调: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
System.out.println("BeanFactoryAware回调");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
System.out.println("ApplicationContextAware回调");
}
}
5. BeanPostProcessor前置处理(postProcessBeforeInitialization)
在初始化方法执行前,BeanPostProcessor可以进行自定义处理。
java
// BeanPostProcessor接口定义
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
// 自定义BeanPostProcessor示例
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("BeanPostProcessor前置处理: " + beanName);
// 可以在这里修改Bean实例
if (bean instanceof MyBean) {
((MyBean) bean).setCustomProperty("processed");
}
return bean;
}
}
6. 初始化方法执行(Initialization)
Spring提供了多种初始化方式:
方式1:@PostConstruct注解
java
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("@PostConstruct初始化方法执行");
// 初始化逻辑
}
}
方式2:实现InitializingBean接口
java
@Component
public class MyBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet()执行");
// 初始化逻辑
}
}
方式3:XML配置init-method
xml
<bean id="myBean" class="com.example.MyBean" init-method="customInit"/>
java
public class MyBean {
public void customInit() {
System.out.println("XML配置的init-method执行");
// 初始化逻辑
}
}
7. BeanPostProcessor后置处理(postProcessAfterInitialization)
在初始化方法执行后,BeanPostProcessor可以进行最终处理。
java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("BeanPostProcessor后置处理: " + beanName);
// 可以在这里创建代理对象(AOP就是在这里实现的)
if (bean instanceof MyService) {
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
new MyInvocationHandler(bean)
);
}
return bean;
}
}
8. Bean就绪(Ready for Use)
此时Bean已经完全初始化,可以被应用程序使用。
9. 销毁阶段(Destruction)
当容器关闭时,Bean会进入销毁阶段。
方式1:@PreDestroy注解
java
@Component
public class MyBean {
@PreDestroy
public void destroy() {
System.out.println("@PreDestroy销毁方法执行");
// 清理资源
}
}
方式2:实现DisposableBean接口
java
@Component
public class MyBean implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean.destroy()执行");
// 清理资源
}
}
方式3:XML配置destroy-method
xml
<bean id="myBean" class="com.example.MyBean" destroy-method="customDestroy"/>
java
public class MyBean {
public void customDestroy() {
System.out.println("XML配置的destroy-method执行");
// 清理资源
}
}
三、完整示例代码
下面是一个完整的Bean生命周期示例:
java
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;
@Component
public class LifecycleDemoBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
private String name;
public LifecycleDemoBean() {
System.out.println("1. 构造函数执行 - 实例化阶段");
}
public void setName(String name) {
this.name = name;
System.out.println("2. 属性赋值: name = " + name);
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware回调: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. BeanFactoryAware回调");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("5. ApplicationContextAware回调");
}
@PostConstruct
public void postConstruct() {
System.out.println("6. @PostConstruct方法执行");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("7. InitializingBean.afterPropertiesSet()执行");
}
public void initMethod() {
System.out.println("8. 自定义init-method执行");
}
public void businessMethod() {
System.out.println("9. 业务方法执行 - Bean已就绪");
}
@PreDestroy
public void preDestroy() {
System.out.println("10. @PreDestroy方法执行");
}
@Override
public void destroy() throws Exception {
System.out.println("11. DisposableBean.destroy()执行");
}
public void destroyMethod() {
System.out.println("12. 自定义destroy-method执行");
}
}
四、BeanPostProcessor的特殊作用
BeanPostProcessor在Spring中扮演着重要角色,AOP、事务管理等都依赖于它:
java
@Component
public class AopBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// AOP代理创建
if (needProxy(bean)) {
return createProxy(bean);
}
return bean;
}
private boolean needProxy(Object bean) {
// 检查是否需要创建代理(基于注解或配置)
return bean.getClass().isAnnotationPresent(Transactional.class) ||
hasAspectAnnotation(bean);
}
private Object createProxy(Object target) {
// 创建JDK动态代理或CGLIB代理
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("Before method: " + method.getName());
// 执行目标方法
Object result = method.invoke(target, args);
// 后置增强
System.out.println("After method: " + method.getName());
return result;
}
}
);
}
}
五、生命周期扩展点总结
| 扩展点 | 触发时机 | 使用场景 |
|---|---|---|
| BeanPostProcessor | 初始化前后 | AOP、属性验证、代理创建 |
| InstantiationAwareBeanPostProcessor | 实例化前后 | 自定义实例化逻辑 |
| DestructionAwareBeanPostProcessor | 销毁前后 | 自定义销毁逻辑 |
| MergedBeanDefinitionPostProcessor | Bean定义合并后 | 修改BeanDefinition |
| SmartInstantiationAwareBeanPostProcessor | 实例化阶段 | 预测Bean类型、选择构造函数 |
六、实际应用建议
- 初始化顺序控制:使用@DependsOn注解或实现SmartInitializingSingleton接口
- 延迟初始化:使用@Lazy注解或配置lazy-init="true"
- 作用域管理:合理使用singleton、prototype、request、session等作用域
- 循环依赖处理:Spring通过三级缓存解决setter注入的循环依赖
结语
深入理解Spring Bean生命周期是掌握Spring框架的关键。通过合理使用生命周期回调,我们可以实现更灵活、更健壮的应用程序。希望本文能帮助你更好地理解和使用Spring Bean生命周期机制。
作者 :fuliyingIT
原文链接 :[你的CSDN博客链接]
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。