Spring Bean的生命周期
Spring Bean 的生命周期是指一个 Bean 从创建到销毁的整个过程,Spring 提供了多个扩展点允许开发者介入这个生命周期。SpringBean创建、实例化、赋值、销毁的过程大致如下:
1. 完整的 Spring Bean 生命周期
- 通过BeanDefinition获取bean的定义信息
- 调用构造函数实例化Bean
- Bean的依赖注入
- 处理Aware接口(BeanFactoryAware,BeamNameAware,ApplicationContextAware)
- Bean的后置处理器BeanPostProcessor前置方法
- 初始化方法(InitializingBean、自定义 init-method)
- Bean的后置处理器BeanPostProcessor后置方法
- Bean 就绪可用
- 销毁Bean(@PreDestroy 注解方法、DisposableBean.destroy()、自定义 destroy-method)
从图中可以看到,Bean创建的起点是从BeanDefinition这个对象开始的,BeanDefinition是 Spring 容器中用于描述 Bean 的配置元数据的对象。简单来说,BeanDefinition 定义了 Spring 如何创建和管理一个 Bean 的所有必要信息。BeanDefinition 是一个配置元数据对象,它包含了创建一个 Bean 实例所需的所有配置信息,相当于 Bean 的"蓝图"或"配方"。Spring 容器(如 ApplicationContext)会根据 BeanDefinition 来实例化、配置和组装 Bean。
BeanDefinition属性大致如下:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 设置/获取父定义名称
void setParentName(@Nullable String parentName);
String getParentName();
// 设置/获取 Bean 类名
void setBeanClassName(@Nullable String beanClassName);
String getBeanClassName();
// 设置/获取作用域
void setScope(@Nullable String scope);
String getScope();
// 设置/获取是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 设置/获取依赖的 Bean
void setDependsOn(@Nullable String... dependsOn);
String[] getDependsOn();
// 设置/获取是否自动装配候选
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
// 设置/获取是否主候选
void setPrimary(boolean primary);
boolean isPrimary();
// 设置/获取工厂方法名
void setFactoryMethodName(@Nullable String factoryMethodName);
String getFactoryMethodName();
// 设置/获取初始化方法名
void setInitMethodName(@Nullable String initMethodName);
String getInitMethodName();
// 设置/获取销毁方法名
void setDestroyMethodName(@Nullable String destroyMethodName);
String getDestroyMethodName();
}
代码演示
1. 创建演示 Bean
package com.example.demo.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. 属性赋值 - setName: " + name);
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware.setBeanName: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. BeanFactoryAware.setBeanFactory");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("5. ApplicationContextAware.setApplicationContext");
}
@PostConstruct
public void postConstruct() {
System.out.println("7. @PostConstruct 方法调用");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("8. InitializingBean.afterPropertiesSet");
}
public void customInit() {
System.out.println("9. 自定义 init-method");
}
@PreDestroy
public void preDestroy() {
System.out.println("12. @PreDestroy 方法调用");
}
@Override
public void destroy() throws Exception {
System.out.println("13. DisposableBean.destroy");
}
public void customDestroy() {
System.out.println("14. 自定义 destroy-method");
}
public void doSomething() {
System.out.println("11. Bean 使用中...");
}
}
2. 创建 BeanPostProcessor
package com.example.demo.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 (bean instanceof LifeCycleBean) {
System.out.println("6. BeanPostProcessor.postProcessBeforeInitialization: " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifeCycleBean) {
System.out.println("10. BeanPostProcessor.postProcessAfterInitialization: " + beanName);
}
return bean;
}
}
3. 配置类
package com.example.demo.config;
import com.example.demo.bean.LifeCycleBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifeCycleBean lifeCycleBean() {
LifeCycleBean bean = new LifeCycleBean();
bean.setName("测试Bean");
return bean;
}
}
4. 主程序
package com.example.demo;
import com.example.demo.bean.LifeCycleBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
LifeCycleBean bean = context.getBean(LifeCycleBean.class);
bean.doSomething();
context.close();
}
}
执行结果分析
运行程序后,控制台输出如下:
1. 构造器调用 - 实例化
2. 属性赋值 - setName: 测试Bean
3. BeanNameAware.setBeanName: lifeCycleBean
4. BeanFactoryAware.setBeanFactory
5. ApplicationContextAware.setApplicationContext
6. BeanPostProcessor.postProcessBeforeInitialization: lifeCycleBean
7. @PostConstruct 方法调用
8. InitializingBean.afterPropertiesSet
9. 自定义 init-method
10. BeanPostProcessor.postProcessAfterInitialization: lifeCycleBean
11. Bean 使用中...
12. @PreDestroy 方法调用
13. DisposableBean.destroy
14. 自定义 destroy-method
生命周期阶段详解
实例化阶段
- 调用构造方法创建 Bean 实例
属性赋值阶段
- 通过 setter 方法或字段注入依赖
Aware 接口回调
- 如果实现了
BeanNameAware
,调用setBeanName()
- 如果实现了
BeanFactoryAware
,调用setBeanFactory()
- 如果实现了
ApplicationContextAware
,调用setApplicationContext()
- 如果实现了
初始化前处理
BeanPostProcessor.postProcessBeforeInitialization()
初始化阶段
- 调用
@PostConstruct
注解的方法 - 如果实现了
InitializingBean
,调用afterPropertiesSet()
- 调用自定义的
init-method
- 调用
初始化后处理
BeanPostProcessor.postProcessAfterInitialization()
使用阶段
- Bean 已经完全初始化,可以被应用程序使用
销毁阶段
- 调用
@PreDestroy
注解的方法 - 如果实现了
DisposableBean
,调用destroy()
- 调用自定义的
destroy-method
- 调用
生命周期扩展点总结
扩展点 | 说明 | 执行顺序 |
---|---|---|
BeanPostProcessor | 可以在初始化前后对 Bean 进行处理 | 最早和最晚 |
@PostConstruct | JSR-250 标准注解 | InitializingBean 之前 |
InitializingBean | Spring 提供的接口 | 在 @PostConstruct 之后 |
init-method | XML 或 @Bean 中指定的方法 | 在 InitializingBean 之后 |
@PreDestroy | JSR-250 标准注解 | DisposableBean 之前 |
DisposableBean | Spring 提供的接口 | 在 @PreDestroy 之后 |
destroy-method | XML 或 @Bean 中指定的方法 | 最后执行 |
实际应用建议
初始化逻辑:
- 优先使用
@PostConstruct
注解(标准方式) - 其次考虑
InitializingBean
(Spring 专有) - 最后使用
init-method
(兼容旧代码)
- 优先使用
销毁逻辑:
- 优先使用
@PreDestroy
注解 - 其次考虑
DisposableBean
- 最后使用
destroy-method
- 优先使用
BeanPostProcessor:
- 适合对所有 Bean 进行统一处理
- 常用于代理创建、属性修改等场景