Spring Bean 生命周期到底经历了什么?从实例化到销毁的全链路拆解
用了这么多年 Spring,Bean 生命周期还是说不全?
@PostConstruct和InitializingBean谁先执行?BeanPostProcessor和Aware接口谁先谁后?今天从源码出发,把 Bean 从创建到销毁的每一步都拆清楚。读完这篇,面试问到 Bean 生命周期,你能画出完整时序图。
一、Bean 生命周期全景图
Spring Bean 生命周期(完整时序)
│
├── 1. 实例化(Instantiation)
│ ├── 构造方法反射创建实例
│ └── 如果有 @Lookup → 生成 CGLIB 代理
│
├── 2. 属性赋值(Populate)
│ ├── @Autowired 注入
│ ├── @Value 注入
│ └── setter 方法注入
│
├── 3. Aware 接口回调
│ ├── BeanNameAware.setBeanName()
│ ├── BeanClassLoaderAware.setBeanClassLoader()
│ ├── BeanFactoryAware.setBeanFactory()
│ ├── EnvironmentAware.setEnvironment()
│ ├── ApplicationContextAware.setApplicationContext()
│ └── 其他 Aware...
│
├── 4. BeanPostProcessor 前置处理
│ └── postProcessBeforeInitialization()
│
├── 5. 初始化(Initialization)
│ ├── @PostConstruct
│ ├── InitializingBean.afterPropertiesSet()
│ └── custom init-method
│
├── 6. BeanPostProcessor 后置处理
│ ├── postProcessAfterInitialization()
│ ├── AOP 代理在此生成
│ └── 事务代理在此生成
│
├── 7. 就绪(Ready)
│ └── Bean 可被使用
│
└── 8. 销毁(Destruction)
├── @PreDestroy
├── DisposableBean.destroy()
└── custom destroy-method
二、实例化:Bean 怎么被创建?
2.1 构造方法选择
// SimpleInstantiationStrategy 的核心逻辑
public Object instantiate(RootBeanDefinition bd) {
// 1. 优先无参构造
Constructor<?> constructor = bd.getConstructor();
if (constructor == null) {
constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
}
// 2. 反射创建实例
return constructor.newInstance();
}
构造方法选择规则
│
├── 只有一个构造方法 → 直接用
├── 有多个构造方法
│ ├── 有 @Autowired 的 → 用标注的那个
│ ├── 有无参构造 → 用无参
│ └── 都没有无参 → 报错
│
└── 注意:构造方法注入无法被代理!
└── 因为代理对象也需要构造
2.2 三级缓存提前曝光
循环依赖场景下,Bean 会提前暴露半成品引用:
// DefaultSingletonBeanRegistry
// 一开始就放入三级缓存
addSingletonFactory(beanName,
() -> getEarlyBeanReference(beanName, mbd, bean));
详细的循环依赖分析见本系列第 1 篇。
三、属性赋值:依赖注入怎么发生?
实例化后,Spring 填充 Bean 的属性:
// AbstractAutowireCapableBeanFactory.populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd,
BeanWrapper bw) {
// 1. InstantiationAwareBeanPostProcessor 后置处理
// 可以在这里修改属性值,甚至跳过注入
if (hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessors()) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 有 PostProcessor 说"跳过注入"
}
}
}
// 2. 自动注入(byName / byType)
PropertyValues pvs = mbd.getPropertyValues();
// 3. @Autowired / @Value 注入
// 通过 AutowiredAnnotationBeanPostProcessor 处理
// 4. CommonAnnotationBeanPostProcessor 处理 @Resource
}
属性注入顺序
│
├── 1. @Autowired(byType)
├── 2. @Qualifier(指定名称)
├── 3. @Resource(byName 优先)
├── 4. @Value(配置值注入)
└── 5. setter 方法
│
└── 注意:同一个属性注入多次,后者覆盖前者
四、Aware 接口回调
Spring 提供了大量 Aware 接口,让 Bean 获取容器信息:
// AbstractAwareProcessor 伪代码
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware bna) {
bna.setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware bcla) {
bcla.setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware bfa) {
bfa.setBeanFactory(this);
}
}
}
ApplicationContextAware 触发位置
注意:ApplicationContextAware 不是在上面方法里调用的,而是在 ApplicationContextAwareProcessor 中:
// ApplicationContextAwareProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof EnvironmentAware eaw) eaw.setEnvironment(this.environment);
if (bean instanceof ResourceLoaderAware raw) raw.setResourceLoader(this.applicationContext);
if (bean instanceof ApplicationEventPublisherAware aepa)
aepa.setApplicationEventPublisher(this.applicationContext);
if (bean instanceof MessageSourceAware msa) msa.setMessageSource(this.applicationContext);
if (bean instanceof ApplicationContextAware aca)
aca.setApplicationContext(this.applicationContext);
return bean;
}
关键点:ApplicationContextAware 是通过 BeanPostProcessor 的前置方法回调的,不是直接调用。
Aware 回调顺序
│
├── BeanNameAware ← 直接调用
├── BeanClassLoaderAware ← 直接调用
├── BeanFactoryAware ← 直接调用
│
├── --- 以下在 BeanPostProcessor#before 中 ---
│
├── EnvironmentAware
├── EmbeddedValueResolverAware
├── ResourceLoaderAware
├── ApplicationEventPublisherAware
├── MessageSourceAware
├── ApplicationContextAware
└── 其他自定义 Aware
五、BeanPostProcessor:最强大的扩展点
5.1 前置和后置方法
public interface BeanPostProcessor {
// 初始化前调用
default Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
// 初始化后调用
default Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
5.2 AOP 代理在哪里生成?
答案:在 postProcessAfterInitialization 中。
// AbstractAutoProxyCreator
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 在这里创建代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
代理创建时机
│
├── 正常流程 → postProcessAfterInitialization 中创建
├── 循环依赖 → getEarlyBeanReference 中提前创建
│ └── 提前创建的代理会在 earlyProxyReferences 中记录
│ 避免重复创建
└── 代理只能创建一次!
六、初始化:三种方式及其顺序
// AbstractAutowireCapableBeanFactory.initializeBean()
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. Aware 回调(上一节已讲)
invokeAwareMethods(beanName, bean);
// 2. BeanPostProcessor#before
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 3. 初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 4. BeanPostProcessor#after(AOP 代理在这)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
6.1 invokeInitMethods 源码
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
// 1. InitializingBean.afterPropertiesSet()
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
// 2. 自定义 init-method
if (mbd != null && mbd.getInitMethodName() != null) {
String initMethodName = mbd.getInitMethodName();
// 防止重复执行
if (!(isInitializingBean && "afterPropertiesSet".equals(initMethodName))) {
Method initMethod = mbd.getInitMethod();
initMethod.invoke(bean);
}
}
}
注意:@PostConstruct 不在这里调用!它由
InitDestroyAnnotationBeanPostProcessor在 BeanPostProcessor#before 阶段处理。
6.2 完整初始化顺序
初始化顺序(严格!)
│
├── Step 1: BeanPostProcessor#before
│ └── InitDestroyAnnotationBeanPostProcessor 处理 @PostConstruct
│
├── Step 2: InitializingBean.afterPropertiesSet()
│
└── Step 3: custom init-method
│
└── 结论:@PostConstruct → afterPropertiesSet → init-method
验证代码:
@Component
public class LifecycleBean implements InitializingBean {
@PostConstruct
public void postConstruct() {
log.info("1. @PostConstruct");
}
@Override
public void afterPropertiesSet() {
log.info("2. afterPropertiesSet");
}
// @Bean(initMethod = "customInit")
public void customInit() {
log.info("3. custom init-method");
}
}
七、销毁:三种方式及其顺序
容器关闭时,Bean 按注册逆序销毁。
7.1 销毁顺序
销毁顺序
│
├── Step 1: @PreDestroy
│ └── 由 InitDestroyAnnotationBeanPostProcessor 处理
│
├── Step 2: DisposableBean.destroy()
│
└── Step 3: custom destroy-method
7.2 源码
// DisposableBeanAdapter
public void destroy() {
// 1. @PreDestroy
if (this.invokeMethods) {
DestructionAwareBeanPostProcessor bp = ...
bp.postProcessBeforeDestruction(this.bean, this.beanName);
}
// 2. DisposableBean.destroy()
if (this.bean instanceof DisposableBean disposable) {
disposable.destroy();
}
// 3. custom destroy-method
if (this.destroyMethod != null) {
this.destroyMethod.invoke(this.bean);
}
}
八、完整生命周期时序图
// 用一个 Bean 验证完整生命周期
@Component
public class FullLifecycleBean implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean {
public FullLifecycleBean() {
log.info("1. 构造方法");
}
@Autowired
public void setDependency(SomeDependency dep) {
log.info("2. 属性注入(setter)");
}
@Override
public void setBeanName(String name) {
log.info("3. BeanNameAware.setBeanName");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
log.info("4. BeanFactoryAware.setBeanFactory");
}
@Override
public void setApplicationContext(ApplicationContext ctx) {
log.info("5. ApplicationContextAware.setApplicationContext");
}
@PostConstruct
public void postConstruct() {
log.info("6. @PostConstruct");
}
@Override
public void afterPropertiesSet() {
log.info("7. InitializingBean.afterPropertiesSet");
}
// init-method (via @Bean(initMethod="customInit"))
public void customInit() {
log.info("8. custom init-method");
}
@PreDestroy
public void preDestroy() {
log.info("9. @PreDestroy");
}
@Override
public void destroy() {
log.info("10. DisposableBean.destroy");
}
// destroy-method (via @Bean(destroyMethod="customDestroy"))
public void customDestroy() {
log.info("11. custom destroy-method");
}
}
输出(验证):
1. 构造方法
2. 属性注入(setter)
3. BeanNameAware.setBeanName
4. BeanFactoryAware.setBeanFactory
5. ApplicationContextAware.setApplicationContext
6. @PostConstruct
7. InitializingBean.afterPropertiesSet
8. custom init-method
--- 应用运行中 ---
9. @PreDestroy
10. DisposableBean.destroy
11. custom destroy-method
九、常见问题与陷阱
9.1 构造方法中能用 @Autowired 字段吗?
@Component
public class WrongExample {
@Autowired
private SomeService service;
public WrongExample() {
// service 还没注入,这里是 null!
service.doSomething(); // NPE
}
}
原因
│
├── 构造方法执行时,Bean 刚实例化
├── 属性注入在构造方法之后
└── 解决方案
├── 方案 1:构造方法注入(推荐)
├── 方案 2:@PostConstruct 中使用
└── 方案 3:setter 中使用
9.2 BeanPostProcessor 影响 Bean 生命周期吗?
影响!
│
├── BeanPostProcessor 本身也是 Bean
├── 它必须比业务 Bean 先初始化
├── Spring 在 refresh() 的第 6 步注册所有 BeanPostProcessor
│
└── 关键规则
├── BeanPostProcessor 不能 @Autowired 业务 Bean
│ └── 因为 BeanPostProcessor 先初始化,业务 Bean 还没创建
└── 如果在 BeanPostProcessor 中注入业务 Bean
└── 那个 Bean 会提前创建,跳过某些 PostProcessor
9.3 Prototype Bean 的销毁
Prototype Bean 的生命周期
│
├── 创建、注入、初始化 → 和 Singleton 一样
├── 容器不管理 Prototype Bean 的销毁!
├── 需要自己调用销毁方法
└── 实现 DisposableBean + 手动调用 destroy()
9.4 @Lazy 对生命周期的影响
@Lazy Bean
│
├── 容器启动时不创建
├── 首次使用时才走完整生命周期
└── 单例 + @Lazy = 延迟初始化的单例
十、面试速答模板
Q:Spring Bean 生命周期?
分四阶段:实例化(构造方法)→ 属性注入(@Autowired/@Resource)→ 初始化(@PostConstruct → afterPropertiesSet → init-method)→ 销毁(@PreDestroy → destroy → destroy-method)。中间穿插 Aware 回调和 BeanPostProcessor 处理,AOP 代理在 BeanPostProcessor 后置方法中生成。
Q:@PostConstruct 和 InitializingBean 谁先执行?
@PostConstruct 先执行。因为 @PostConstruct 由 InitDestroyAnnotationBeanPostProcessor 在 BeanPostProcessor#before 阶段处理,而 afterPropertiesSet 在 before 之后调用。完整顺序:@PostConstruct → afterPropertiesSet → custom init-method。
Q:AOP 代理在什么时候生成?
正常流程下,在 BeanPostProcessor#afterInitialization 中由 AbstractAutoProxyCreator 创建。循环依赖时,在 getEarlyBeanReference 中提前创建。两个位置不会重复创建,通过 earlyProxyReferences 去重。
下一篇我们聊 Spring Boot 自动配置源码拆解:@Conditional 条件注解怎么生效的?spring.factories 到 AutoConfigurationImportSelector 的完整链路是什么?自动配置类为什么能被排除?
本文是 Java 技术系列第 9 篇,系列目录: