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 的核心逻辑publicObjectinstantiate(RootBeanDefinitionbd){// 1. 优先无参构造Constructor<?>constructor=bd.getConstructor();if(constructor==null){constructor=clazz.getDeclaredConstructor();constructor.setAccessible(true);}// 2. 反射创建实例returnconstructor.newInstance();}构造方法选择规则 │ ├── 只有一个构造方法 → 直接用 ├── 有多个构造方法 │ ├── 有 @Autowired 的 → 用标注的那个 │ ├── 有无参构造 → 用无参 │ └── 都没有无参 → 报错 │ └── 注意:构造方法注入无法被代理! └── 因为代理对象也需要构造2.2 三级缓存提前曝光
循环依赖场景下,Bean 会提前暴露半成品引用:
// DefaultSingletonBeanRegistry// 一开始就放入三级缓存addSingletonFactory(beanName,()->getEarlyBeanReference(beanName,mbd,bean));详细的循环依赖分析见本系列第 1 篇。
三、属性赋值:依赖注入怎么发生?
实例化后,Spring 填充 Bean 的属性:
// AbstractAutowireCapableBeanFactory.populateBean()protectedvoidpopulateBean(StringbeanName,RootBeanDefinitionmbd,BeanWrapperbw){// 1. InstantiationAwareBeanPostProcessor 后置处理// 可以在这里修改属性值,甚至跳过注入if(hasInstantiationAwareBeanPostProcessors()){for(InstantiationAwareBeanPostProcessorbp:getBeanPostProcessors()){if(!bp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)){return;// 有 PostProcessor 说"跳过注入"}}}// 2. 自动注入(byName / byType)PropertyValuespvs=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 伪代码privatevoidinvokeAwareMethods(StringbeanName,Objectbean){if(beaninstanceofAware){if(beaninstanceofBeanNameAwarebna){bna.setBeanName(beanName);}if(beaninstanceofBeanClassLoaderAwarebcla){bcla.setBeanClassLoader(getBeanClassLoader());}if(beaninstanceofBeanFactoryAwarebfa){bfa.setBeanFactory(this);}}}ApplicationContextAware 触发位置
注意:ApplicationContextAware不是在上面方法里调用的,而是在ApplicationContextAwareProcessor中:
// ApplicationContextAwareProcessorpublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofEnvironmentAwareeaw)eaw.setEnvironment(this.environment);if(beaninstanceofResourceLoaderAwareraw)raw.setResourceLoader(this.applicationContext);if(beaninstanceofApplicationEventPublisherAwareaepa)aepa.setApplicationEventPublisher(this.applicationContext);if(beaninstanceofMessageSourceAwaremsa)msa.setMessageSource(this.applicationContext);if(beaninstanceofApplicationContextAwareaca)aca.setApplicationContext(this.applicationContext);returnbean;}关键点:ApplicationContextAware 是通过 BeanPostProcessor 的前置方法回调的,不是直接调用。
Aware 回调顺序 │ ├── BeanNameAware ← 直接调用 ├── BeanClassLoaderAware ← 直接调用 ├── BeanFactoryAware ← 直接调用 │ ├── --- 以下在 BeanPostProcessor#before 中 --- │ ├── EnvironmentAware ├── EmbeddedValueResolverAware ├── ResourceLoaderAware ├── ApplicationEventPublisherAware ├── MessageSourceAware ├── ApplicationContextAware └── 其他自定义 Aware五、BeanPostProcessor:最强大的扩展点
5.1 前置和后置方法
publicinterfaceBeanPostProcessor{// 初始化前调用defaultObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){returnbean;}// 初始化后调用defaultObjectpostProcessAfterInitialization(Objectbean,StringbeanName){returnbean;}}5.2 AOP 代理在哪里生成?
答案:在 postProcessAfterInitialization 中。
// AbstractAutoProxyCreatorpublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(bean!=null){ObjectcacheKey=getCacheKey(bean.getClass(),beanName);if(this.earlyProxyReferences.remove(cacheKey)!=bean){// 在这里创建代理returnwrapIfNecessary(bean,beanName,cacheKey);}}returnbean;}代理创建时机 │ ├── 正常流程 → postProcessAfterInitialization 中创建 ├── 循环依赖 → getEarlyBeanReference 中提前创建 │ └── 提前创建的代理会在 earlyProxyReferences 中记录 │ 避免重复创建 └── 代理只能创建一次!六、初始化:三种方式及其顺序
// AbstractAutowireCapableBeanFactory.initializeBean()protectedObjectinitializeBean(StringbeanName,Objectbean,RootBeanDefinitionmbd){// 1. Aware 回调(上一节已讲)invokeAwareMethods(beanName,bean);// 2. BeanPostProcessor#beforeObjectwrappedBean=applyBeanPostProcessorsBeforeInitialization(bean,beanName);// 3. 初始化方法invokeInitMethods(beanName,wrappedBean,mbd);// 4. BeanPostProcessor#after(AOP 代理在这)wrappedBean=applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);returnwrappedBean;}6.1 invokeInitMethods 源码
protectedvoidinvokeInitMethods(StringbeanName,Objectbean,RootBeanDefinitionmbd)throwsThrowable{// 1. InitializingBean.afterPropertiesSet()booleanisInitializingBean=(beaninstanceofInitializingBean);if(isInitializingBean){((InitializingBean)bean).afterPropertiesSet();}// 2. 自定义 init-methodif(mbd!=null&&mbd.getInitMethodName()!=null){StringinitMethodName=mbd.getInitMethodName();// 防止重复执行if(!(isInitializingBean&&"afterPropertiesSet".equals(initMethodName))){MethodinitMethod=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验证代码:
@ComponentpublicclassLifecycleBeanimplementsInitializingBean{@PostConstructpublicvoidpostConstruct(){log.info("1. @PostConstruct");}@OverridepublicvoidafterPropertiesSet(){log.info("2. afterPropertiesSet");}// @Bean(initMethod = "customInit")publicvoidcustomInit(){log.info("3. custom init-method");}}七、销毁:三种方式及其顺序
容器关闭时,Bean 按注册逆序销毁。
7.1 销毁顺序
销毁顺序 │ ├── Step 1: @PreDestroy │ └── 由 InitDestroyAnnotationBeanPostProcessor 处理 │ ├── Step 2: DisposableBean.destroy() │ └── Step 3: custom destroy-method7.2 源码
// DisposableBeanAdapterpublicvoiddestroy(){// 1. @PreDestroyif(this.invokeMethods){DestructionAwareBeanPostProcessorbp=...bp.postProcessBeforeDestruction(this.bean,this.beanName);}// 2. DisposableBean.destroy()if(this.beaninstanceofDisposableBeandisposable){disposable.destroy();}// 3. custom destroy-methodif(this.destroyMethod!=null){this.destroyMethod.invoke(this.bean);}}八、完整生命周期时序图
// 用一个 Bean 验证完整生命周期@ComponentpublicclassFullLifecycleBeanimplementsBeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{publicFullLifecycleBean(){log.info("1. 构造方法");}@AutowiredpublicvoidsetDependency(SomeDependencydep){log.info("2. 属性注入(setter)");}@OverridepublicvoidsetBeanName(Stringname){log.info("3. BeanNameAware.setBeanName");}@OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){log.info("4. BeanFactoryAware.setBeanFactory");}@OverridepublicvoidsetApplicationContext(ApplicationContextctx){log.info("5. ApplicationContextAware.setApplicationContext");}@PostConstructpublicvoidpostConstruct(){log.info("6. @PostConstruct");}@OverridepublicvoidafterPropertiesSet(){log.info("7. InitializingBean.afterPropertiesSet");}// init-method (via @Bean(initMethod="customInit"))publicvoidcustomInit(){log.info("8. custom init-method");}@PreDestroypublicvoidpreDestroy(){log.info("9. @PreDestroy");}@Overridepublicvoiddestroy(){log.info("10. DisposableBean.destroy");}// destroy-method (via @Bean(destroyMethod="customDestroy"))publicvoidcustomDestroy(){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 字段吗?
@ComponentpublicclassWrongExample{@AutowiredprivateSomeServiceservice;publicWrongExample(){// 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 会提前创建,跳过某些 PostProcessor9.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 篇,系列目录:
- Spring 循环依赖三级缓存源码拆解
- Spring 事务失效 7 种场景
- Spring Boot 自动配置原理
- Spring AOP 代理选择与原理
- JVM 内存模型与 GC 调优
- MyBatis-Plus 插件机制原理
- Spring 事件机制与监听器模式
- Spring Boot 启动流程源码拆解
- 本文:Spring Bean 生命周期全链路拆解