Spring Bean 生命周期
深入理解 Spring Bean 从创建到销毁的完整生命周期,包括实例化、属性赋值、初始化和销毁四大阶段
Spring Bean 的生命周期
Spring 不仅仅是 new 了一个对象,它是在对象创建的前、中、后各个环节都留出了窗口,允许你像做手术一样精准地修改这个对象的行为。
一、 概览:Bean 生命周期的四大阶段
如果把 Spring Bean 比作一个人 🧍,它的生命周期可以粗略地分为这四个主要阶段:
- 实例化 (Instantiation):
- 相当于“出生”。Spring 容器通过反射机制在堆内存中申请空间,创建一个原始的对象。此时,对象中的属性还是默认值(如 null)。
- 属性赋值 (Populate Properties):
- 相当于“成长的补给”。Spring 将配置文件中定义的属性值、或者通过
@Autowired注解引用的其他依赖 Bean,注入到这个对象中。
- 初始化 (Initialization):
- 相当于“成年礼/岗前培训”。这是最复杂的一步,对象虽然有了数据,但可能还需要进行各种配置检查、连接数据库资源、或者被 AOP 代理包装,这一步完成后,Bean 才是真正可用的。
- 销毁 (Destruction):
- 相当于“退休/离世”。当容器关闭时,需要清理资源(如关闭数据库连接、IO 流)。
二、 详细执行顺序
在上述四大阶段之间,Spring 穿插了非常多的 扩展点(Hook),让开发者可以介入 Bean 的创建过程。以下是严格的执行顺序:
1. 实例化阶段
- Step 1: 实例化 Bean (Instantiation)
- 调用构造函数(Constructor)。
2. 属性赋值阶段
- Step 2: 填充属性 (Populate Properties)
- 调用 Setter 方法或直接注入字段(Dependency Injection)。
3. 初始化阶段(核心)
Step 3: 检查 Aware 接口 (Aware Interfaces)
- 如果 Bean 实现了
BeanNameAware,调用setBeanName(告诉 Bean 它自己的名字)。 - 如果 Bean 实现了
BeanFactoryAware,调用setBeanFactory(让 Bean 能获取到工厂本身)。 - (注:还有其他 Aware,如
ApplicationContextAware)
Step 4: BeanPostProcessor - 前置处理 (Before)
- 关键点:调用
BeanPostProcessor.postProcessBeforeInitialization()。 - 这是容器级别的扩展,对 所有 Bean 都生效。通常用于修改 Bean 的原始属性。
Step 5: 初始化方法 (Initialization Methods)
- a. 调用
@PostConstruct注解的方法(JSR-250 标准)。 - b. 调用
InitializingBean.afterPropertiesSet()方法。 - c. 调用 XML 中配置的
init-method或@Bean(initMethod = "...")指定的方法。
Step 6: BeanPostProcessor - 后置处理 (After)
- 关键点:调用
BeanPostProcessor.postProcessAfterInitialization()。 - AOP 的发生地:Spring 的 AOP 动态代理通常是在这一步完成的。如果需要代理,这里返回的将是代理对象,而不是原始对象。
4. 使用阶段
Step 7: Bean 准备就绪
- 此时 Bean 已经存在于 Spring 容器中,可以被其他对象引用和使用了。
5. 销毁阶段
Step 8: 销毁方法 (Destruction Methods)
- a. 调用
@PreDestroy注解的方法。 - b. 调用
DisposableBean.destroy()接口方法。 - c. 调用自定义的
destroy-method。
三、 代码实例演示
为了直观地看到这个顺序,我们写一个简单的 Spring Boot 例子。
1. 定义一个全功能的 Bean
这个 Bean 实现了生命周期中涉及的大部分接口。
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;
public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
private String name;
public LifeCycleBean() {
System.out.println("1. [实例化] 调用构造函数");
}
public void setName(String name) {
this.name = name;
System.out.println("2. [属性赋值] 调用 Setter 方法设置属性: " + name);
}
@Override
public void setBeanName(String s) {
System.out.println("3. [Aware接口] 调用 BeanNameAware.setBeanName: " + s);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. [Aware接口] 调用 BeanFactoryAware.setBeanFactory");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("5. [Aware接口] 调用 ApplicationContextAware.setApplicationContext");
}
// 注意:Step 6 (PostProcessor Before) 在外部类中
@PostConstruct
public void myPostConstruct() {
System.out.println("7. [初始化] 调用 @PostConstruct 注解方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("8. [初始化] 调用 InitializingBean.afterPropertiesSet()");
}
public void myInitMethod() {
System.out.println("9. [初始化] 调用自定义 init-method");
}
// 注意:Step 10 (PostProcessor After) 在外部类中
@PreDestroy
public void myPreDestroy() {
System.out.println("11. [销毁] 调用 @PreDestroy 注解方法");
}
@Override
public void destroy() throws Exception {
System.out.println("12. [销毁] 调用 DisposableBean.destroy()");
}
public void myDestroyMethod() {
System.out.println("13. [销毁] 调用自定义 destroy-method");
}
}
2. 定义一个后置处理器 (BeanPostProcessor)
这是一个 拦截器,会拦截所有的 Bean。
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("6. [PostProcessor] postProcessBeforeInitialization (初始化前置)");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("10. [PostProcessor] postProcessAfterInitialization (初始化后置 - AOP代理常在此处)");
}
return bean;
}
}
3. 配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LifeCycleConfig {
@Bean(initMethod = "myInitMethod", destroyMethod = "myDestroyMethod")
public LifeCycleBean lifeCycleBean() {
LifeCycleBean bean = new LifeCycleBean();
bean.setName("设置 name 属性");
return bean;
}
}
上面代码比较占位置,这里贴一个 tab 标签展示风格的
四、 运行结果
当你启动并关闭 Spring 容器时,控制台将严格按照以下顺序打印:
1. [实例化] 调用构造函数
2. [属性赋值] 调用 Setter 方法设置属性: 设置 name 属性
3. [Aware接口] 调用 BeanNameAware.setBeanName: lifeCycleBean
4. [Aware接口] 调用 BeanFactoryAware.setBeanFactory
5. [Aware接口] 调用 ApplicationContextAware.setApplicationContext
6. [PostProcessor] postProcessBeforeInitialization (初始化前置)
7. [初始化] 调用 @PostConstruct 注解方法
8. [初始化] 调用 InitializingBean.afterPropertiesSet()
9. [初始化] 调用自定义 init-method
10. [PostProcessor] postProcessAfterInitialization (初始化后置 - AOP代理常在此处)
... (此时 Bean 可在应用中使用) ...
... (容器关闭) ...
11. [销毁] 调用 @PreDestroy 注解方法
12. [销毁] 调用 DisposableBean.destroy()
13. [销毁] 调用自定义 destroy-method
五、 动画演示
Spring Bean 生命周期
从实例化到销毁的全过程深度解析
1. 实例化 (Instantiation)
调用构造函数 Constructor,在堆内存中申请空间。
2. 属性赋值 (Populate)
调用 Setter 或字段注入,填充 @Autowired 依赖。
3. Aware 接口回调
BeanNameAware, BeanFactoryAware... 通知 Bean 自身环境信息。
4. BeanPostProcessor (Before)
初始化前置处理。修改原始 Bean 的最后机会。
5. 初始化方法
@PostConstruct → afterPropertiesSet() → init-method
6. BeanPostProcessor (After)
AOP 关键点。动态代理通常在此处生成。
7. Bean 准备就绪
Bean 进入容器单例池,可被应用使用。
8. 销毁 (Destruction)
容器关闭。@PreDestroy → DisposableBean → destroy-method