跳到主要内容

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 会注入相应的资源:

AwareInterfaces.java
@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 接口:

接口注入内容
BeanNameAwareBean 的名称
BeanFactoryAwareBeanFactory 引用
ApplicationContextAwareApplicationContext 引用
EnvironmentAwareEnvironment 对象
ResourceLoaderAware资源加载器

④⑧ BeanPostProcessor

BeanPostProcessor 是 Spring 最重要的扩展点,作用于所有 Bean

CustomBeanPostProcessor.java
@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;
}
}
重要的内置 BeanPostProcessor
  • AutowiredAnnotationBeanPostProcessor:处理 @Autowired 注入
  • CommonAnnotationBeanPostProcessor:处理 @PostConstruct@PreDestroy@Resource
  • AbstractAutoProxyCreator:创建 AOP 代理

⑤⑥⑦ 初始化阶段

三种初始化方式按以下顺序执行:

InitializationOrder.java
@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 按以下顺序销毁:

DestructionOrder.java
@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");
}
}
prototype Bean 不会被容器销毁

Spring 只负责 singleton Bean 的完整生命周期。prototype Bean 创建后交给调用者,容器不管理其销毁

完整生命周期代码演示

LifecycleBean.java
@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 的区别和执行顺序?

答案

执行顺序:@PostConstructafterPropertiesSet()init-method

方式标准耦合度推荐度
@PostConstructJSR-250 标准低(不依赖 Spring)推荐
InitializingBeanSpring 接口高(Spring 耦合)框架内部使用
init-method配置指定第三方库使用

Q3: BeanPostProcessor 的作用?

答案

BeanPostProcessor 是 Spring 最重要的扩展机制,它会对容器中所有 Bean 生效。有两个回调方法:

  • postProcessBeforeInitialization:初始化前(处理 @PostConstruct)
  • postProcessAfterInitialization:初始化后(创建 AOP 代理)

Spring 内部大量功能通过 BeanPostProcessor 实现:@Autowired 注入、@PostConstruct 处理、AOP 代理创建等。

Q4: BeanFactoryPostProcessor 和 BeanPostProcessor 的区别?

答案

对比BeanFactoryPostProcessorBeanPostProcessor
执行时机Bean 实例化之前Bean 实例化之后
操作对象BeanDefinition(Bean 定义)Bean 实例
用途修改 Bean 的定义信息修改或包装 Bean 实例
典型实现PropertySourcesPlaceholderConfigurerAutowiredAnnotationBeanPostProcessor

Q5: Spring AOP 代理在 Bean 生命周期的哪个阶段创建?

答案

在 BeanPostProcessor 的 postProcessAfterInitialization() 阶段。具体是 AbstractAutoProxyCreator 检查 Bean 是否匹配 AOP 切面规则,如果匹配则创建代理对象替代原始 Bean 放入容器。

Q6: prototype Bean 的生命周期有什么不同?

答案

  • 创建流程与 singleton 相同(实例化→注入→初始化)
  • Spring 不缓存 prototype Bean,每次 getBean() 都创建新实例
  • Spring 不管理其销毁阶段(@PreDestroyDisposableBean.destroy() 不会被调用)
  • 调用者需自行管理 prototype Bean 的资源释放

相关链接