文章
Spring中Bean的生命周期
Spring IoC 容器负责管理 Bean 的整个生命周期,从创建到销毁。
Spring Bean 生命周期的核心阶段#
Spring IoC 容器负责管理 Bean 的整个生命周期,从创建到销毁。一个典型的 Bean 生命周期主要包括以下几个阶段:
- 实例化 (Instantiation)
- 概述: 这是 Bean 生命周期的第一步,容器通过调用 Bean 的构造器来创建 Bean 的实例。
- 过程: Spring 容器根据 Bean 定义(通过
@Component、@Service、@Repository、@Controller或@Bean方法定义)来创建 Bean 的一个原始实例。此时,实例已经存在于内存中,但其属性尚未被填充。
- 属性填充 (Populating Properties / Dependency Injection)
- 概述: 容器为 Bean 的属性设置值,并注入其依赖的其他 Bean。
- 过程: 在实例被创建后,Spring 容器会检查 Bean 的所有属性。如果这些属性是其他 Bean 的引用(例如通过
@Autowired、@Resource或setter方法注入),容器会查找并注入这些依赖。这个阶段是依赖注入(DI)发生的主要阶段。
- 初始化 (Initialization)
- 概述: 在属性填充完成后,Bean 会经历一系列的初始化回调,允许在 Bean 投入使用之前执行一些自定义的设置或准备工作。
- 过程: 这个阶段是执行自定义初始化逻辑的最佳时机。Spring 提供了多种方式来执行初始化回调:
- A. BeanNameAware: 如果 Bean 实现了
org.springframework.beans.factory.BeanNameAware接口,Spring 会调用其setBeanName(String name)方法,将 Bean 的 ID 传递给 Bean 自身。 - B. BeanFactoryAware: 如果 Bean 实现了
org.springframework.beans.factory.BeanFactoryAware接口,Spring 会调用其setBeanFactory(BeanFactory beanFactory)方法,将当前 BeanFactory 实例传递给 Bean。 - C. ApplicationContextAware: 如果 Bean 实现了
org.springframework.context.ApplicationContextAware接口,Spring 会调用其setApplicationContext(ApplicationContext applicationContext)方法,将当前 ApplicationContext 实例传递给 Bean。 - D. BeanPostProcessors (前置处理): 如果容器中注册了
org.springframework.beans.factory.config.BeanPostProcessor接口的实现类,Spring 会在此时调用其postProcessBeforeInitialization(Object bean, String beanName)方法。这是一个非常强大的扩展点,允许在任何 Bean 初始化之前对其进行修改。 - E.
@PostConstruct注解: 如果 Bean 的方法上标注了javax.annotation.PostConstruct注解(需要jakarta.annotation-api或javax.annotation-api依赖),Spring 会在依赖注入完成后,调用这个方法。这是最常用的初始化回调方式。 - F. InitializingBean 接口: 如果 Bean 实现了
org.springframework.beans.factory.InitializingBean接口,Spring 会调用其afterPropertiesSet()方法。 - G. 自定义 ****
init-method: 在 XML 配置中,可以通过init-method属性指定一个方法作为初始化回调。在 Java 配置中,@Bean注解可以指定initMethod属性。
- A. BeanNameAware: 如果 Bean 实现了
@Bean(initMethod = "customInit")
public MyBean myBean() {
return new MyBean();
}
- **H. BeanPostProcessors (后置处理)**: 最后,Spring 会调用 `BeanPostProcessor` 的 `postProcessAfterInitialization(Object bean, String beanName)` 方法。这也是一个重要的扩展点,例如 Spring AOP 就是在这个阶段通过 `BeanPostProcessor` 来创建代理对象的。 4. **使用中 (In Use)** - **概述**: Bean 已经完全初始化并准备就绪,可以被应用程序使用了。 - **过程**: 一旦 Bean 初始化完成,它就被存储在 Spring IoC 容器中,等待被其他 Bean 引用或通过 `applicationContext.getBean()` 方法获取并使用。 5. **销毁 (Destruction)** - **概述**: 当 Spring 容器关闭时,或当 Bean 的作用域结束时(例如,对于单例 Bean,当容器关闭时;对于请求作用域 Bean,当请求结束时),Bean 会经历销毁回调,释放资源。 - **过程**: 这个阶段是执行自定义清理逻辑的最佳时机,例如关闭数据库连接、文件句柄等。销毁回调的触发方式与初始化回调类似: - **A. ****`@PreDestroy`**** 注解**: 如果 Bean 的方法上标注了 `javax.annotation.PreDestroy` 注解,Spring 会在 Bean 销毁之前调用这个方法。这是最常用的销毁回调方式。 - **B. DisposableBean 接口**: 如果 Bean 实现了 `org.springframework.beans.factory.DisposableBean` 接口,Spring 会调用其 `destroy()` 方法。 - **C. 自定义 ****`destroy-method`**: 在 XML 配置中,可以通过 `destroy-method` 属性指定一个方法作为销毁回调。在 Java 配置中,`@Bean` 注解可以指定 `destroyMethod` 属性。 java
@Bean(destroyMethod = "customDestroy")
public MyBean myBean() {
return new MyBean();
}
```
演示代码示例#
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct; // for @PostConstruct
import javax.annotation.PreDestroy; // for @PreDestroy
// 假设我们的项目中引入了 jakarta.annotation-api 依赖,因为 Spring Boot 3+ 倾向于 Jakarta EE
// 如果是 Spring Boot 2.x,可能需要 javax.annotation-api
@Configuration
public class MySpringBeanLifecycleConfig {
@Bean(initMethod = "beanCustomInit", destroyMethod = "beanCustomDestroy")
public MyLifecycleBean myLifecycleBean() {
return new MyLifecycleBean();
}
@Bean
public MyCustomBeanPostProcessor myCustomBeanPostProcessor() {
return new MyCustomBeanPostProcessor();
}
public static void main(String[] args) {
System.out.println("--- Spring 容器开始初始化 ---");
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MySpringBeanLifecycleConfig.class);
System.out.println("--- Spring 容器初始化完成 ---");
MyLifecycleBean bean = context.getBean(MyLifecycleBean.class);
bean.doSomething();
System.out.println("--- 关闭 Spring 容器 ---");
context.close();
System.out.println("--- Spring 容器已关闭 ---");
}
}
class MyLifecycleBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
public MyLifecycleBean() {
System.out.println("1. Bean 实例化: MyLifecycleBean 构造器被调用");
}
// 2. 属性填充 (这里没有依赖注入,所以不会有输出)
// --- 初始化阶段 ---
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("2.1 BeanNameAware: setBeanName 被调用,Bean 名称: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("2.2 BeanFactoryAware: setBeanFactory 被调用");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("2.3 ApplicationContextAware: setApplicationContext 被调用");
}
// BeanPostProcessor 的 beforeInitialization 发生在 setBeanName, setBeanFactory, setApplicationContext 之后,但在 @PostConstruct/InitializingBean/init-method 之前
@PostConstruct
public void postConstructMethod() {
System.out.println("2.4 @PostConstruct: postConstructMethod 被调用");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("2.5 InitializingBean: afterPropertiesSet 被调用");
}
public void beanCustomInit() {
System.out.println("2.6 Custom Init Method (via @Bean initMethod): beanCustomInit 被调用");
}
// BeanPostProcessor 的 afterInitialization 发生在 @PostConstruct/InitializingBean/init-method 之后
// --- 使用中 ---
public void doSomething() {
System.out.println("3. Bean 使用中: doSomething() 方法被调用");
}
// --- 销毁阶段 ---
@PreDestroy
public void preDestroyMethod() {
System.out.println("4.1 @PreDestroy: preDestroyMethod 被调用");
}
@Override
public void destroy() throws Exception {
System.out.println("4.2 DisposableBean: destroy() 被调用");
}
public void beanCustomDestroy() {
System.out.println("4.3 Custom Destroy Method (via @Bean destroyMethod): beanCustomDestroy 被调用");
}
}
class MyCustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyLifecycleBean) {
System.out.println("BPP (Before Init): Bean '" + beanName + "' -> postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyLifecycleBean) {
System.out.println("BPP (After Init): Bean '" + beanName + "' -> postProcessAfterInitialization");
}
return bean;
}
}
运行上述代码,你将看到以下(或类似)的输出顺序,这清晰地展示了 Bean 的生命周期:
-- Spring 容器开始初始化 ---<br>1. Bean 实例化: MyLifecycleBean 构造器被调用<br>2.1 BeanNameAware: setBeanName 被调用,Bean 名称: myLifecycleBean<br>2.2 BeanFactoryAware: setBeanFactory 被调用<br>2.3 ApplicationContextAware: setApplicationContext 被调用<br>BPP (Before Init): Bean 'myLifecycleBean' -> postProcessBeforeInitialization<br>2.4 @PostConstruct: postConstructMethod 被调用<br>2.5 InitializingBean: afterPropertiesSet 被调用<br>2.6 Custom Init Method (via @Bean initMethod): beanCustomInit 被调用<br>BPP (After Init): Bean 'myLifecycleBean' -> postProcessAfterInitialization<br>--- Spring 容器初始化完成 ---<br>3. Bean 使用中: doSomething() 方法被调用<br>--- 关闭 Spring 容器 ---<br>4.1 @PreDestroy: preDestroyMethod 被调用<br>4.2 DisposableBean: destroy() 被调用<br>4.3 Custom Destroy Method (via @Bean destroyMethod): beanCustomDestroy 被调用<br>--- Spring 容器已关闭 ---
总结#
Spring(Spring Boot)的 Bean 生命周期管理是一个强大且灵活的机制。它通过一系列回调方法和接口(如 Aware 接口、InitializingBean、DisposableBean)以及注解(@PostConstruct、@PreDestroy)来允许开发者在 Bean 的不同阶段插入自定义逻辑。
其中,BeanPostProcessor**** 是最强大的扩展点,因为它可以在任何 Bean 初始化前后对其进行干预,Spring 内部的许多高级功能(如 AOP、事务代理)都是基于 BeanPostProcessor 实现的。理解这些阶段对于高级的 Spring 开发、性能调优和故障排查至关重要。