Bean 生命周期
问题
Spring Bean 的完整生命周期是怎样的?BeanPostProcessor 在什么阶段执行?@PostConstruct 和 InitializingBean 的执行顺序?
答案
Bean 生命周期全流程
各阶段详解
① 实例化
Spring 通过反射(或 CGLIB)创建 Bean 的原始对象:
// 底层调用 Constructor.newInstance()
Object bean = beanClass.getDeclaredConstructor().newInstance();
② 属性填充(依赖注入)
将依赖注入到 Bean 中(@Autowired、@Value 等):
@Service
public class UserService {
@Autowired
private UserDao userDao; // 在此阶段注入
@Value("${app.name}")
private String appName; // 在此阶段注入
}
③ Aware 接口回调
如果 Bean 实现了 Aware 接口,Spring 会注入相应的资源:
@Component
public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
@Override
public void setBeanName(String name) {
// 获取 Bean 在容器中的名称
}
@Override
public void setBeanFactory(BeanFactory factory) {
// 获取 BeanFactory 引用
}
@Override
public void setApplicationContext(ApplicationContext ctx) {
// 获取 ApplicationContext 引用
}
}
常用 Aware 接口:
| 接口 | 注入内容 |
|---|---|
| BeanNameAware | Bean 的名称 |
| BeanFactoryAware | BeanFactory 引用 |
| ApplicationContextAware | ApplicationContext 引用 |
| EnvironmentAware | Environment 对象 |
| ResourceLoaderAware | 资源加载器 |
④⑧ BeanPostProcessor
BeanPostProcessor 是 Spring 最重要的扩展点,作用于所有 Bean:
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
// ④ 初始化前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 可以对 bean 进行修改或包装
// @PostConstruct 就是在这里被处理的
return bean;
}
// ⑧ 初始化后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// AOP 代理就是在这里创建的
// 如果需要代理,返回代理对象替代原始 bean
return bean;
}
}
AutowiredAnnotationBeanPostProcessor:处理@Autowired注入CommonAnnotationBeanPostProcessor:处理@PostConstruct、@PreDestroy、@ResourceAbstractAutoProxyCreator:创建 AOP 代理
⑤⑥⑦ 初始化阶段
三种初始化方式按以下顺序执行:
@Component
public class MyBean implements InitializingBean {
// ⑤ 第一个执行:@PostConstruct(JSR-250 标准注解)
@PostConstruct
public void postConstruct() {
System.out.println("1. @PostConstruct");
}
// ⑥ 第二个执行:InitializingBean 接口
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("2. InitializingBean.afterPropertiesSet()");
}
// ⑦ 第三个执行:自定义 init-method
// 通过 @Bean(initMethod = "customInit") 指定
public void customInit() {
System.out.println("3. custom init-method");
}
}
⑩⑪⑫ 销毁阶段
容器关闭时,单例 Bean 按以下顺序销毁:
@Component
public class MyBean implements DisposableBean {
// ⑩ 第一个执行
@PreDestroy
public void preDestroy() {
System.out.println("1. @PreDestroy");
}
// ⑪ 第二个执行
@Override
public void destroy() throws Exception {
System.out.println("2. DisposableBean.destroy()");
}
// ⑫ 第三个执行
// 通过 @Bean(destroyMethod = "customDestroy") 指定
public void customDestroy() {
System.out.println("3. custom destroy-method");
}
}
Spring 只负责 singleton Bean 的完整生命周期。prototype Bean 创建后交给调用者,容器不管理其销毁。
完整生命周期代码演示
@Component
public class LifecycleBean implements BeanNameAware, InitializingBean, DisposableBean {
public LifecycleBean() {
System.out.println("1. 构造函数(实例化)");
}
@Autowired
public void setDependency(SomeDependency dep) {
System.out.println("2. 属性填充(依赖注入)");
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware.setBeanName: " + name);
}
@PostConstruct
public void postConstruct() {
System.out.println("5. @PostConstruct");
}
@Override
public void afterPropertiesSet() {
System.out.println("6. InitializingBean.afterPropertiesSet");
}
@PreDestroy
public void preDestroy() {
System.out.println("10. @PreDestroy");
}
@Override
public void destroy() {
System.out.println("11. DisposableBean.destroy");
}
}
常见面试问题
Q1: Spring Bean 的生命周期?
答案:
核心流程:实例化 → 属性填充 → Aware 回调 → BeanPostProcessor 前置 → 初始化(@PostConstruct → InitializingBean → init-method) → BeanPostProcessor 后置 → 使用 → 销毁(@PreDestroy → DisposableBean → destroy-method)。
Q2: @PostConstruct、InitializingBean、init-method 的区别和执行顺序?
答案:
执行顺序:@PostConstruct → afterPropertiesSet() → init-method。
| 方式 | 标准 | 耦合度 | 推荐度 |
|---|---|---|---|
| @PostConstruct | JSR-250 标准 | 低(不依赖 Spring) | 推荐 |
| InitializingBean | Spring 接口 | 高(Spring 耦合) | 框架内部使用 |
| init-method | 配置指定 | 低 | 第三方库使用 |
Q3: BeanPostProcessor 的作用?
答案:
BeanPostProcessor 是 Spring 最重要的扩展机制,它会对容器中所有 Bean 生效。有两个回调方法:
postProcessBeforeInitialization:初始化前(处理 @PostConstruct)postProcessAfterInitialization:初始化后(创建 AOP 代理)
Spring 内部大量功能通过 BeanPostProcessor 实现:@Autowired 注入、@PostConstruct 处理、AOP 代理创建等。
Q4: BeanFactoryPostProcessor 和 BeanPostProcessor 的区别?
答案:
| 对比 | BeanFactoryPostProcessor | BeanPostProcessor |
|---|---|---|
| 执行时机 | Bean 实例化之前 | Bean 实例化之后 |
| 操作对象 | BeanDefinition(Bean 定义) | Bean 实例 |
| 用途 | 修改 Bean 的定义信息 | 修改或包装 Bean 实例 |
| 典型实现 | PropertySourcesPlaceholderConfigurer | AutowiredAnnotationBeanPostProcessor |
Q5: Spring AOP 代理在 Bean 生命周期的哪个阶段创建?
答案:
在 BeanPostProcessor 的 postProcessAfterInitialization() 阶段。具体是 AbstractAutoProxyCreator 检查 Bean 是否匹配 AOP 切面规则,如果匹配则创建代理对象替代原始 Bean 放入容器。
Q6: prototype Bean 的生命周期有什么不同?
答案:
- 创建流程与 singleton 相同(实例化→注入→初始化)
- Spring 不缓存 prototype Bean,每次
getBean()都创建新实例 - Spring 不管理其销毁阶段(
@PreDestroy和DisposableBean.destroy()不会被调用) - 调用者需自行管理 prototype Bean 的资源释放
相关链接
- Spring Bean Lifecycle 官方文档
- IoC 容器与依赖注入 - Bean 的创建和注入
- AOP 面向切面编程 - AOP 代理在生命周期中的位置
- 循环依赖 - 三级缓存与生命周期的关系