Spring Bean 的生命周期是指从 Bean 的创建到销毁的整个过程,这个过程由 Spring IoC 容器管理。理解 Bean 的生命周期可以帮助我们在控制 Bean 的初始化和销毁行为,以及在 Bean 生命周期的不同阶段执行自定义逻辑。
以下是 Spring Bean 的完整生命周期,包括各个阶段以及可以介入的方法:
1. 实例化 (Instantiation):
- Bean 定义加载: Spring 容器读取 Bean 定义(XML 配置、Java 注解、Java 配置类)。
- 创建 Bean 实例: Spring 容器使用 Java 反射机制,通过构造函数(或工厂方法)创建 Bean 的实例。
- 构造函数注入: 如果使用构造函数注入,Spring 会在此时解析并注入构造函数参数。
2. 属性填充 (Populate Properties):
- Setter 注入: Spring 容器根据 Bean 定义中的属性配置,调用 Bean 的 Setter 方法,注入依赖的 Bean 或值。
- 字段注入: Spring 容器直接通过反射设置 Bean 的字段值(不推荐)。
- 自动装配: 如果启用了自动装配(byType、byName、constructor),Spring 会自动查找并注入依赖。
- 类型转换: 如果属性的类型与配置值的类型不匹配,Spring 会尝试进行类型转换。
3. Aware 接口回调:
- 如果 Bean 实现了 Spring 提供的 Aware 接口,Spring 容器会在属性注入完成后、初始化之前调用这些接口的方法,将相应的资源注入到 Bean 中。
- 常见的 Aware 接口:
BeanNameAware: 注入 Bean 的名称。BeanFactoryAware: 注入BeanFactory实例。ApplicationContextAware: 注入ApplicationContext实例。EnvironmentAware: 注入Environment实例(用于获取配置属性)。ResourceLoaderAware: 注入ResourceLoader实例(用于加载资源)。MessageSourceAware: 注入MessageSource实例(用于国际化)。ApplicationEventPublisherAware: 注入ApplicationEventPublisher实例(用于发布事件).
- 调用顺序:
BeanNameAwareBeanClassLoaderAwareBeanFactoryAware- 其他Aware接口
4. BeanPostProcessor 前置处理:
postProcessBeforeInitialization: Spring 容器调用所有已注册的BeanPostProcessor的postProcessBeforeInitialization方法。- 允许在 Bean 初始化之前对 Bean 进行修改或执行其他操作(例如,AOP 代理就是在这里创建的)。
- 可以返回修改后的 Bean,也可以返回原始的 Bean。
5. 初始化 (Initialization):
InitializingBean接口: 如果 Bean 实现了InitializingBean接口,Spring 容器会调用其afterPropertiesSet方法。@PostConstruct注解: 如果 Bean 的方法上有@PostConstruct注解,Spring 容器会调用该方法。init-method属性: 如果 Bean 定义中指定了init-method属性(XML 配置),Spring 容器会调用指定的方法(通过反射)。- 执行顺序:
@PostConstructInitializingBean.afterPropertiesSetinit-method
6. BeanPostProcessor 后置处理:
postProcessAfterInitialization: Spring 容器调用所有已注册的BeanPostProcessor的postProcessAfterInitialization方法。- 允许在 Bean 初始化之后对 Bean 进行修改或执行其他操作。
- 可以返回修改后的 Bean,也可以返回原始的 Bean。
7. Bean 就绪 (Ready to Use):
- Bean 现在已经完全初始化,可以被应用程序使用了。
- 对于单例 Bean,Spring 容器会将其缓存起来,以便后续使用。
- 对于原型 Bean,每次请求都会创建一个新的实例。
8. 销毁 (Destruction): (仅当容器关闭, 且Bean的作用域是singleton时)
DisposableBean接口: 如果 Bean 实现了DisposableBean接口,Spring 容器会调用其destroy方法。@PreDestroy注解: 如果 Bean 的方法上有@PreDestroy注解,Spring 容器会调用该方法。destroy-method属性: 如果 Bean 定义中指定了destroy-method属性(XML 配置),Spring 容器会调用指定的方法(通过反射)。- 执行顺序:
@PreDestroyDisposableBean.destroydestroy-method
总结流程图:
+-------------------+
| 1. Bean 定义加载 |
+-------------------+
|
V
+-------------------+
| 2. 实例化 | (构造函数/工厂方法)
+-------------------+
|
V
+-------------------+
| 3. 属性填充 | (Setter/字段注入, 自动装配, 类型转换)
+-------------------+
|
V
+-------------------+
| 4. Aware 接口回调 | (BeanNameAware, BeanFactoryAware, ...)
+-------------------+
|
V
+-------------------+
| 5. BeanPostProcessor | (postProcessBeforeInitialization)
| 前置处理 |
+-------------------+
|
V
+-------------------+
| 6. 初始化 | (InitializingBean, @PostConstruct, init-method)
+-------------------+
|
V
+-------------------+
| 7. BeanPostProcessor | (postProcessAfterInitialization)
| 后置处理 |
+-------------------+
|
V
+-------------------+
| 8. Bean 就绪 |
+-------------------+
|
| (容器关闭, 且Bean的作用域是singleton)
V
+-------------------+
| 9. 销毁 | (DisposableBean, @PreDestroy, destroy-method)
+-------------------+
关键接口和注解:
BeanPostProcessor: 允许在 Bean 初始化前后进行处理。InitializingBean: 提供afterPropertiesSet方法,在 Bean 属性设置完成后执行初始化逻辑。DisposableBean: 提供destroy方法,在 Bean 销毁前执行清理逻辑。@PostConstruct: 标记初始化方法。@PreDestroy: 标记销毁方法。- Aware 接口: 用于注入容器提供的资源。
示例 (包含完整生命周期):
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.BeansException;
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.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class MyBean implements InitializingBean, DisposableBean, BeanNameAware, BeanPostProcessor {
private String name;
public MyBean() {
System.out.println("1. Bean 实例化 (构造函数)");
}
public void setName(String name) {
System.out.println("2. 属性填充 (setName)");
this.name = name;
}
@Override
public void setBeanName(String name) {
System.out.println("3. Aware 接口回调 (BeanNameAware): " + name);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("4. BeanPostProcessor 前置处理 (postProcessBeforeInitialization): " + beanName);
return bean;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5. 初始化 (InitializingBean.afterPropertiesSet)");
}
@PostConstruct
public void customInit() {
System.out.println("6. 初始化 (@PostConstruct)");
}
public void myInitMethod() {
System.out.println("7. 初始化 (init-method)");
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("8. BeanPostProcessor 后置处理 (postProcessAfterInitialization): " + beanName);
return bean;
}
public void start() {
System.out.println("9. Bean 就绪, 执行业务逻辑 (start)");
}
@Override
public void destroy() throws Exception {
System.out.println("10. 销毁 (DisposableBean.destroy)");
}
@PreDestroy
public void customDestroy() {
System.out.println("11. 销毁 (@PreDestroy)");
}
public void myDestroyMethod() {
System.out.println("12. 销毁 (destroy-method)");
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取 Bean
MyBean myBean = context.getBean(MyBean.class);
// 使用 Bean
myBean.start();
// 关闭容器
((ClassPathXmlApplicationContext) context).close();
}
}
applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.example"/> <!-- 替换为你的包名 -->
<bean id="myBean" class="com.example.MyBean" init-method="myInitMethod" destroy-method="myDestroyMethod">
<property name="name" value="My Bean"/>
</bean>
</beans>
输出结果:
1. Bean 实例化 (构造函数)
2. 属性填充 (setName)
3. Aware 接口回调 (BeanNameAware): myBean
4. BeanPostProcessor 前置处理 (postProcessBeforeInitialization): myBean
6. 初始化 (@PostConstruct)
5. 初始化 (InitializingBean.afterPropertiesSet)
7. 初始化 (init-method)
8. BeanPostProcessor 后置处理 (postProcessAfterInitialization): myBean
9. Bean 就绪, 执行业务逻辑 (start)
11. 销毁 (@PreDestroy)
10. 销毁 (DisposableBean.destroy)
12. 销毁 (destroy-method)
注意:
- Spring Boot 大大简化了 Spring 的配置,但 Bean 的生命周期仍然遵循上述步骤。
BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法会对 所有 的Bean生效。

1474

被折叠的 条评论
为什么被折叠?



