Appearance
Spring Bean的生命周期
要理解Spring Bean的生命周期,核心是掌握从Bean的创建→初始化→使用→销毁的完整流程,以及Spring容器在每个阶段对Bean的干预逻辑。以下是**细致到“每一步做什么、涉及哪些接口/注解、顺序如何”**的拆解: 
一、先明确:Spring生命周期的核心对象
Spring的生命周期管理依赖两个核心组件:
- BeanFactory:Spring的“Bean工厂”,负责Bean的创建、配置、管理(最基础的容器)。
- ApplicationContext:BeanFactory的扩展,增加了事件发布、国际化、AOP等功能,默认自动初始化单例Bean(BeanFactory是懒加载)。
我们常说的“Spring生命周期”,本质是ApplicationContext管理下的Bean生命周期(更贴近实际开发场景)。
二、Spring Bean生命周期的完整流程(单例Bean)
单例Bean(默认Scope)的生命周期与容器同生共死(容器启动时创建,容器关闭时销毁)。以下是按执行顺序排列的11个关键步骤,结合接口/注解/配置的作用:
1. 阶段1:Bean定义的加载与解析
- 操作:Spring容器启动时,加载
@Component、@Bean、XML<bean>等Bean定义(BeanDefinition),解析成BeanDefinition对象(包含Bean的类名、属性、Scope、初始化方法等元数据)。 - 举例:
@Component标注的类会被ComponentScan扫描到,生成对应的BeanDefinition。
2. 阶段2:Bean的实例化(Instantiation)
- 操作:Spring根据
BeanDefinition的元数据,创建Bean的实例(内存中分配对象)。 - 实例化方式:
- 默认:调用无参构造器(若有参,需配合
@Autowired或<constructor-arg>注入)。 - 静态工厂方法:如
@Bean public static MyBean createBean()(调用静态方法创建实例)。 - 实例工厂方法:如
@Bean public MyBean createBean(OtherBean other)(调用现有Bean的方法创建实例)。
- 默认:调用无参构造器(若有参,需配合
- 注意:此时Bean的属性(如
@Autowired标注的字段)还未赋值,只是一个“空壳”对象。
3. 阶段3:属性注入(Populate Properties)
- 操作:Spring根据
BeanDefinition中的配置(如@Autowired、@Value、<property>),将依赖的Bean或值注入到当前Bean的属性中。 - 关键机制:
- 自动注入(Autowiring):通过类型(byType)或名称(byName)匹配依赖。
- 外部值注入:通过
@Value("${config.key}")读取配置文件的值。
- 举例:java
@Component public class UserService { @Autowired // 属性注入 private UserDao userDao; } - 注意:属性注入完成后,Bean的基本状态才完整。
4. 阶段4:Aware接口的回调(注入容器上下文)
- 操作:若Bean实现了Aware接口(Spring提供的“感知”接口),Spring会将对应的容器资源注入到Bean中,让Bean能访问容器的内部信息。
- 常见Aware接口及作用:
接口 方法 作用 BeanNameAwaresetBeanName(String name)注入当前Bean在容器中的名称 BeanFactoryAwaresetBeanFactory(BeanFactory)注入BeanFactory(容器本身) ApplicationContextAwaresetApplicationContext(ApplicationContext)注入ApplicationContext(更强大的容器) ResourceLoaderAwaresetResourceLoader(ResourceLoader)注入资源加载器(用于读取文件) - 举例:java
@Component public class MyBean implements BeanNameAware { @Override public void setBeanName(String name) { System.out.println("当前Bean的名称:" + name); // 输出:myBean } } - 顺序:Aware接口的回调在属性注入之后(因为需要Bean先有完整的属性)。
5. 阶段5:BeanPostProcessor的前置处理(增强Bean)
- 操作:若容器中有BeanPostProcessor(Bean后置处理器),Spring会调用其
postProcessBeforeInitialization方法,在初始化前对Bean进行增强。 - 作用:这是Spring扩展的核心点(如AOP、事务代理都是通过此机制实现)。
- 举例:自定义BeanPostProcessor:java
@Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof UserService) { System.out.println("初始化前增强:" + beanName); } return bean; // 返回增强后的Bean(若不修改则返回原对象) } } - 注意:所有Bean都会经过BeanPostProcessor的处理(除非过滤)。
6. 阶段6:初始化(Initialization)
- 操作:Bean完成属性注入和前置增强后,执行自定义的初始化逻辑(如初始化连接池、加载缓存)。
- 初始化的3种方式(执行顺序从先到后):
@PostConstruct注解(JSR-250规范):标注在非静态方法上,Spring通过CommonAnnotationBeanPostProcessor处理。InitializingBean接口(Spring自带):实现afterPropertiesSet()方法。init-method配置:通过XML<bean init-method="init">或@Bean(initMethod = "init")指定。
- 举例:java
@Component public class UserService implements InitializingBean { @PostConstruct public void postConstruct() { System.out.println("1. @PostConstruct执行"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("2. InitializingBean执行"); } public void init() { // 对应@Bean(initMethod = "init") System.out.println("3. init-method执行"); } } - 执行顺序验证:
@PostConstruct→InitializingBean→init-method。
7. 阶段7:BeanPostProcessor的后置处理(最终增强)
- 操作:调用BeanPostProcessor的
postProcessAfterInitialization方法,在初始化后对Bean进行最终增强。 - 典型场景:AOP代理就是在此步骤生成的——若Bean需要被代理(如
@Transactional标注),Spring会返回代理对象而非原Bean。 - 举例(续阶段5的MyBeanPostProcessor):java
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof UserService) { System.out.println("初始化后增强:" + beanName); } return bean; }
8. 阶段8:Bean的使用(In Use)
- 操作:此时Bean已完全初始化,可以被容器或用户获取并使用(如通过
context.getBean(UserService.class)获取)。 - 注意:单例Bean会被缓存到容器的
singletonObjectsmap中,后续获取直接从缓存取。
9. 阶段9:容器关闭前的准备(Pre-Shutdown)
- 操作:当容器即将关闭(如
context.close()或JVM退出),Spring会触发销毁前的准备(如发布ContextClosedEvent事件)。
10. 阶段10:销毁(Destruction)
- 操作:执行自定义的销毁逻辑(如关闭连接池、释放文件流)。
- 销毁的3种方式(执行顺序从先到后):
@PreDestroy注解(JSR-250规范):标注在非静态方法上。DisposableBean接口(Spring自带):实现destroy()方法。destroy-method配置:通过XML<bean destroy-method="destroy">或@Bean(destroyMethod = "destroy")指定。
- 举例:java
@Component public class UserService implements DisposableBean { @PreDestroy public void preDestroy() { System.out.println("1. @PreDestroy执行"); } @Override public void destroy() throws Exception { System.out.println("2. DisposableBean执行"); } public void destroy() { // 对应@Bean(destroyMethod = "destroy") System.out.println("3. destroy-method执行"); } } - 执行顺序验证:
@PreDestroy→DisposableBean→destroy-method。
11. 阶段11:Bean的回收(GC)
- 操作:销毁完成后,Bean不再被容器引用,最终被JVM垃圾回收。
三、不同Scope对生命周期的影响
Spring的Scope(作用域)决定了Bean的创建时机和生命周期:
- Singleton(单例,默认):
- 生命周期:与容器一致(容器启动时创建,容器关闭时销毁)。
- 场景:无状态的Bean(如Service、Dao)。
- Prototype(原型):
- 生命周期:每次
getBean()时创建,容器不负责销毁(需用户手动处理)。 - 场景:有状态的Bean(如Request级别的Model)。
- 生命周期:每次
- Request(请求域,Web场景):
- 生命周期:每个HTTP请求创建一个Bean,请求结束时销毁。
- Session(会话域,Web场景):
- 生命周期:每个HTTP Session创建一个Bean,会话过期时销毁。
- Application(应用域,Web场景):
- 生命周期:与ServletContext一致(Web应用启动时创建,关闭时销毁)。
四、关键接口/注解的执行顺序总结
将前面的步骤简化为核心顺序链(单例Bean):
Bean定义加载 → 实例化(构造器) → 属性注入(@Autowired) → Aware接口(BeanNameAware) →
BeanPostProcessor前置处理 → 初始化(@PostConstruct → InitializingBean → init-method) →
BeanPostProcessor后置处理 → 使用 → 销毁(@PreDestroy → DisposableBean → destroy-method) → GC五、为什么要理解Spring生命周期?
- 自定义扩展:通过
BeanPostProcessor、Aware接口等扩展Spring功能(如自定义注解、AOP)。 - 排查问题:解决Bean初始化失败、依赖注入异常等问题(如
@PostConstruct执行顺序错误)。 - 资源管理:确保资源在销毁时正确释放(如数据库连接池、Redis连接)。
六、示例:完整生命周期的代码验证
以下代码可以直观看到生命周期的执行顺序:
java
// 1. 自定义Bean(覆盖主要生命周期步骤)
@Component
public class LifeCycleBean implements BeanNameAware, InitializingBean, DisposableBean {
// 阶段2:实例化(构造器)
public LifeCycleBean() {
System.out.println("1. 实例化:构造器执行");
}
// 阶段3:属性注入(@Autowired)
@Autowired
public void setUserDao(UserDao userDao) {
System.out.println("2. 属性注入:UserDao已注入");
}
// 阶段4:Aware接口(BeanNameAware)
@Override
public void setBeanName(String name) {
System.out.println("3. Aware接口:Bean名称为" + name);
}
// 阶段5:BeanPostProcessor前置处理(需自定义BeanPostProcessor)
// 阶段6:初始化(@PostConstruct → InitializingBean → init-method)
@PostConstruct
public void postConstruct() {
System.out.println("4. 初始化:@PostConstruct执行");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5. 初始化:InitializingBean执行");
}
public void initMethod() { // 需配置@Bean(initMethod = "initMethod")
System.out.println("6. 初始化:init-method执行");
}
// 阶段7:BeanPostProcessor后置处理(需自定义BeanPostProcessor)
// 阶段8:使用(假设被其他Bean调用)
public void doSomething() {
System.out.println("7. 使用:Bean正在工作");
}
// 阶段10:销毁(@PreDestroy → DisposableBean → destroy-method)
@PreDestroy
public void preDestroy() {
System.out.println("8. 销毁:@PreDestroy执行");
}
@Override
public void destroy() throws Exception {
System.out.println("9. 销毁:DisposableBean执行");
}
public void destroyMethod() { // 需配置@Bean(destroyMethod = "destroyMethod")
System.out.println("10. 销毁:destroy-method执行");
}
}
// 2. 自定义BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifeCycleBean) {
System.out.println("BeanPostProcessor:初始化前增强");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifeCycleBean) {
System.out.println("BeanPostProcessor:初始化后增强");
}
return bean;
}
}
// 3. 配置类(开启组件扫描)
@Configuration
@ComponentScan("com.example")
public class AppConfig {
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public LifeCycleBean lifeCycleBean() {
return new LifeCycleBean();
}
}
// 4. 启动类
public class Application {
public static void main(String[] args) {
// 启动容器(ApplicationContext)
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)) {
// 获取Bean并使用
LifeCycleBean bean = context.getBean(LifeCycleBean.class);
bean.doSomething();
} // 容器自动关闭(触发销毁逻辑)
}
}七、输出结果验证顺序
运行启动类后,输出顺序如下(对应生命周期步骤):
1. 实例化:构造器执行
2. 属性注入:UserDao已注入
3. Aware接口:Bean名称为lifeCycleBean
BeanPostProcessor:初始化前增强
4. 初始化:@PostConstruct执行
5. 初始化:InitializingBean执行
6. 初始化:init-method执行
BeanPostProcessor:初始化后增强
7. 使用:Bean正在工作
8. 销毁:@PreDestroy执行
9. 销毁:DisposableBean执行
10. 销毁:destroy-method执行总结
Spring的生命周期是**“容器主导、Bean参与”的过程:容器负责Bean的创建、注入、管理,Bean通过接口/注解参与自定义逻辑。理解生命周期的核心是掌握各个阶段的顺序和关键扩展点**,这是Spring进阶的基础。
