ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

Spring Bean 生命周期到底经历了什么?从实例化到销毁的全链路拆解 Spring Bean 生命周期到底经历了什么从实例化到销毁的全链路拆解用了这么多年 SpringBean 生命周期还是说不全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?constructorbd.getConstructor();if(constructornull){constructorclazz.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 / byTypePropertyValuespvsmbd.getPropertyValues();// 3. Autowired / Value 注入// 通过 AutowiredAnnotationBeanPostProcessor 处理// 4. CommonAnnotationBeanPostProcessor 处理 Resource}属性注入顺序 │ ├── 1. AutowiredbyType ├── 2. Qualifier指定名称 ├── 3. ResourcebyName 优先 ├── 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){ObjectcacheKeygetCacheKey(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#beforeObjectwrappedBeanapplyBeanPostProcessorsBeforeInitialization(bean,beanName);// 3. 初始化方法invokeInitMethods(beanName,wrappedBean,mbd);// 4. BeanPostProcessor#afterAOP 代理在这wrappedBeanapplyBeanPostProcessorsAfterInitialization(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!nullmbd.getInitMethodName()!null){StringinitMethodNamembd.getInitMethodName();// 防止重复执行if(!(isInitializingBeanafterPropertiesSet.equals(initMethodName))){MethodinitMethodmbd.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(initMethodcustomInit))publicvoidcustomInit(){log.info(8. custom init-method);}PreDestroypublicvoidpreDestroy(){log.info(9. PreDestroy);}Overridepublicvoiddestroy(){log.info(10. DisposableBean.destroy);}// destroy-method (via Bean(destroyMethodcustomDestroy))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 还没注入这里是 nullservice.doSomething();// NPE}}原因 │ ├── 构造方法执行时Bean 刚实例化 ├── 属性注入在构造方法之后 └── 解决方案 ├── 方案 1构造方法注入推荐 ├── 方案 2PostConstruct 中使用 └── 方案 3setter 中使用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 延迟初始化的单例十、面试速答模板QSpring Bean 生命周期分四阶段实例化构造方法→ 属性注入Autowired/Resource→ 初始化PostConstruct → afterPropertiesSet → init-method→ 销毁PreDestroy → destroy → destroy-method。中间穿插 Aware 回调和 BeanPostProcessor 处理AOP 代理在 BeanPostProcessor 后置方法中生成。QPostConstruct 和 InitializingBean 谁先执行PostConstruct 先执行。因为 PostConstruct 由 InitDestroyAnnotationBeanPostProcessor 在 BeanPostProcessor#before 阶段处理而 afterPropertiesSet 在 before 之后调用。完整顺序PostConstruct → afterPropertiesSet → custom init-method。QAOP 代理在什么时候生成正常流程下在 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 生命周期全链路拆解
返回列表