Spring Bean 生命周期到底经历了什么?从实例化到销毁的全链路拆解
2026/8/7 8:58:29 网站建设 项目流程

Spring Bean 生命周期到底经历了什么?从实例化到销毁的全链路拆解

用了这么多年 Spring,Bean 生命周期还是说不全?@PostConstructInitializingBean谁先执行?BeanPostProcessorAware接口谁先谁后?今天从源码出发,把 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-method

7.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 会提前创建,跳过某些 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 篇,系列目录:

  1. Spring 循环依赖三级缓存源码拆解
  2. Spring 事务失效 7 种场景
  3. Spring Boot 自动配置原理
  4. Spring AOP 代理选择与原理
  5. JVM 内存模型与 GC 调优
  6. MyBatis-Plus 插件机制原理
  7. Spring 事件机制与监听器模式
  8. Spring Boot 启动流程源码拆解
  9. 本文:Spring Bean 生命周期全链路拆解

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询