尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

《Java 100 天进阶之路》第74篇:Bean生命周期(2026版)

《Java 100 天进阶之路》第74篇:Bean生命周期(2026版) 第74篇Bean生命周期2026版系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第73篇Spring IoC容器 |➡️ 下一篇第75篇Spring AOP原理️ 本文阅读地图3 分钟速览第73篇搞定了IoC容器的概念本篇深入Bean生命周期。很多开发者用了多年Spring只停留在Autowired注入Bean的表层一旦遇到Bean初始化顺序异常、循环依赖报错、扩展点执行不符合预期等问题就无从下手。搞懂Bean生命周期就是搞懂了Spring IoC容器的核心灵魂Spring全家桶专题持续推进拿下AOP《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送模块核心问题一句话回答生命周期是什么Bean从生到死经历什么实例化 → 属性填充 → 初始化 → 使用 → 销毁实例化Bean对象怎么创建的容器通过反射调用构造函数创建Bean实例属性填充依赖怎么注入的容器通过依赖注入为Bean设置属性值初始化初始化阶段做了哪些事Aware回调 → BeanPostProcessor前置 → 初始化方法 → BeanPostProcessor后置Aware接口Bean怎么感知容器实现BeanNameAware、BeanFactoryAware等接口容器自动回调BeanPostProcessor怎么在初始化前后插一脚实现postProcessBeforeInitialization和postProcessAfterInitialization销毁Bean怎么被销毁容器关闭时执行PreDestroy→DisposableBean.destroy()→ 自定义destroy-method面试最爱问高频考点有哪些见文末 面试小节一、核心知识点1. 什么是Bean生命周期Bean的生命周期指的是一个Bean从创建到销毁的完整过程。Spring IoC容器会按照固定的流程完成Bean的实例化、属性注入、初始化、销毁全生命周期管控。普通对象 vs Bean普通Java对象通过new关键字手动实例化生命周期仅与JVM垃圾回收相关Spring Bean由IoC容器统一管理容器提供了大量可插拔的扩展点允许开发者在生命周期的任意节点介入。普通对象的命运握在开发者手里Bean的命运握在Spring容器手里。2. 为什么需要了解Bean生命周期价值说明问题排查遇到初始化异常、依赖注入问题时能快速定位问题阶段功能扩展通过BeanPostProcessor等扩展点实现AOP、属性加密等高级功能性能优化了解各阶段执行时机避免在初始化阶段执行耗时操作架构设计开发Spring生态中间件时必须充分理解生命周期才能正确集成3. 谁在管理Bean的生命周期Spring中负责管理Bean生命周期的核心类是AbstractAutowireCapableBeanFactory。它定义了创建Bean的模板方法——实例化、属性填充、初始化的顺序固定但具体步骤可以被子类扩展。二、通俗讲解1分钟开心学把Bean的生命周期想象成员工入职流程这个比喻来自网络上的经典总结非常形象① 实例化公司Spring容器根据简历BeanDefinition发出Offer员工来报到——分配工位分配内存人进来了但电脑、工牌都还没配。② 属性填充HR给员工配电脑、工牌、门禁卡——这就是依赖注入把需要的装备依赖的其他Bean配齐。③ Aware回调员工认识一下公司环境——知道自己的工号BeanNameAware、知道HR部门在哪BeanFactoryAware、知道公司在几号楼ApplicationContextAware。④ BeanPostProcessor前置处理入职体检——在正式上岗前做一次检查。⑤ 初始化参加新员工培训PostConstruct、签劳动合同InitializingBean.afterPropertiesSet()、领工服自定义init-method。⑥ BeanPostProcessor后置处理发放工作证——AOP动态代理就是在这里创建的。⑦ 使用正式上岗干活。⑧ 销毁离职交接——还电脑PreDestroy、办离职手续DisposableBean.destroy()、注销工号自定义destroy-method。三、Bean生命周期完整流程15步一个完整的Spring Bean生命周期可以分为四大阶段、15个关键步骤四、各阶段深度拆解4.1 实例化阶段Instantiation容器通过反射机制调用构造函数创建Bean的实例。这是生命周期的起点。实例化 ≠ 初始化实例化只是把人招进来、工位分配好但电脑、工牌都还没配。属性填充和初始化才是配装备、做培训。4.2 属性填充阶段Populate Properties容器通过依赖注入为Bean设置属性值。这是Spring IoC的核心能力——Autowired、Resource等注解的处理都在这个阶段完成。4.3 初始化阶段Initialization这是生命周期中最复杂的阶段包含多个子步骤。执行顺序必须严格遵循顺序步骤说明①BeanNameAware.setBeanName()传递Bean的ID/名称②BeanFactoryAware.setBeanFactory()传递BeanFactory实例③ApplicationContextAware.setApplicationContext()传递ApplicationContext实例④BeanPostProcessor.postProcessBeforeInitialization()初始化前处理⑤PostConstructJSR-250标准注解方式⑥InitializingBean.afterPropertiesSet()接口方式初始化⑦自定义init-methodXML或Bean(initMethod...)指定⑧BeanPostProcessor.postProcessAfterInitialization()初始化后处理关键点PostConstruct→InitializingBean.afterPropertiesSet()→ 自定义init-method的执行顺序是固定的。AOP动态代理在BeanPostProcessor后置处理中创建——所以Transactional、Async等注解在此时生效。4.4 Aware接口详解Aware接口是一组感知接口让Bean能够感知到Spring容器的基础设施。Aware接口回调方法作用BeanNameAwaresetBeanName(String name)获取Bean在容器中的名称BeanFactoryAwaresetBeanFactory(BeanFactory)获取BeanFactory实例ApplicationContextAwaresetApplicationContext(ApplicationContext)获取ApplicationContext实例BeanClassLoaderAwaresetBeanClassLoader(ClassLoader)获取类加载器EnvironmentAwaresetEnvironment(Environment)获取环境配置4.5 BeanPostProcessor详解BeanPostProcessor是Spring中最强大的扩展点之一。它允许开发者在Bean初始化前后插入自定义逻辑。ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){// 初始化前执行——比如检查Bean是否满足某种条件System.out.println(Before initialization: beanName);returnbean;}OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){// 初始化后执行——AOP动态代理在此创建System.out.println(After initialization: beanName);returnbean;}}BeanPostProcessor不是Bean生命周期的一部分但它是在Bean生命周期中起重要作用的组件。4.6 销毁阶段Destruction当容器关闭时会按相反顺序触发销毁逻辑顺序步骤说明①PreDestroyJSR-250标准注解方式②DisposableBean.destroy()接口方式销毁③自定义destroy-methodXML或Bean(destroyMethod...)指定五、代码验证下面通过一个完整的示例来验证Bean生命周期的执行顺序// 1. 自定义Bean ComponentpublicclassLifecycleBeanimplementsBeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{publicLifecycleBean(){System.out.println(① 实例化构造函数);}AutowiredprivateSomeComponentsomeComponent;publicvoidsetSomeComponent(SomeComponentsomeComponent){System.out.println(② 属性填充setSomeComponent);this.someComponentsomeComponent;}OverridepublicvoidsetBeanName(Stringname){System.out.println(③ Aware回调BeanNameAware - name);}OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){System.out.println(④ Aware回调BeanFactoryAware);}OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext){System.out.println(⑤ Aware回调ApplicationContextAware);}PostConstructpublicvoidpostConstruct(){System.out.println(⑥ 初始化PostConstruct);}OverridepublicvoidafterPropertiesSet(){System.out.println(⑦ 初始化InitializingBean.afterPropertiesSet());}Bean(initMethodcustomInit)publicclassMyConfig{// 自定义init-method}publicvoidcustomInit(){System.out.println(⑧ 初始化自定义 init-method);}publicvoiddoWork(){System.out.println(⑨ 使用业务方法被调用);}PreDestroypublicvoidpreDestroy(){System.out.println(⑩ 销毁PreDestroy);}Overridepublicvoiddestroy(){System.out.println(⑪ 销毁DisposableBean.destroy());}publicvoidcustomDestroy(){System.out.println(⑫ 销毁自定义 destroy-method);}}// 2. 自定义BeanPostProcessor ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofLifecycleBean){System.out.println( BeanPostProcessor前置处理);}returnbean;}OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(beaninstanceofLifecycleBean){System.out.println( BeanPostProcessor后置处理AOP代理在此创建);}returnbean;}}// 3. 启动容器 SpringBootApplicationpublicclassApplication{publicstaticvoidmain(String[]args){ConfigurableApplicationContextcontextSpringApplication.run(Application.class,args);LifecycleBeanbeancontext.getBean(LifecycleBean.class);bean.doWork();context.close();// 触发销毁}}执行结果① 实例化构造函数 ② 属性填充setSomeComponent ③ Aware回调BeanNameAware - lifecycleBean ④ Aware回调BeanFactoryAware ⑤ Aware回调ApplicationContextAware BeanPostProcessor前置处理 ⑥ 初始化PostConstruct ⑦ 初始化InitializingBean.afterPropertiesSet() ⑧ 初始化自定义 init-method BeanPostProcessor后置处理AOP代理在此创建 ⑨ 使用业务方法被调用 ⑩ 销毁PreDestroy ⑪ 销毁DisposableBean.destroy() ⑫ 销毁自定义 destroy-method六、避坑要点错误/误区后果正确做法混淆PostConstruct和afterPropertiesSet()的执行顺序依赖初始化顺序错误PostConstruct先执行afterPropertiesSet()后执行在构造函数中调用未注入的属性空指针异常属性注入完成后才能在PostConstruct中使用认为AOP在Bean实例化时就生效Transactional不生效AOP代理在BeanPostProcessor后置处理中创建在BeanPostProcessor中创建新Bean破坏生命周期可能导致循环依赖BeanPostProcessor只做增强处理不创建新Bean忘记调用context.close()销毁方法不执行在Spring Boot中无需手动处理容器会自动关闭七、面试高频考点Q1Spring Bean的生命周期有哪些阶段四个主要阶段①实例化——容器通过反射调用构造函数创建实例②属性填充——通过依赖注入设置属性值③初始化——Aware回调 → BeanPostProcessor前置 →PostConstruct→InitializingBean.afterPropertiesSet()→ 自定义init-method→ BeanPostProcessor后置④销毁——PreDestroy→DisposableBean.destroy()→ 自定义destroy-method。Q2PostConstruct、InitializingBean、init-method的执行顺序顺序是PostConstruct→InitializingBean.afterPropertiesSet()→ 自定义init-method。PostConstruct是JSR-250标准注解优先级最高InitializingBean是Spring接口方式自定义init-method是XML或注解配置方式。Q3AOP代理是在生命周期的哪个阶段创建的AOP动态代理在BeanPostProcessor.postProcessAfterInitialization()中创建。也就是说在Bean完成初始化之后Spring会检查这个Bean是否需要被代理比如是否有Transactional、Async等注解如果需要就创建一个代理对象返回。Q4BeanPostProcessor和BeanFactoryPostProcessor的区别BeanFactoryPostProcessor是容器级别的扩展点在所有Bean实例化之前执行可以修改BeanDefinition元数据。BeanPostProcessor是Bean级别的扩展点在Bean初始化前后执行可以修改Bean实例本身。两者执行时机完全不同。Q5Aware接口的作用是什么Aware接口让Bean能够感知Spring容器的基础设施。比如BeanNameAware让Bean知道自己的名字ApplicationContextAware让Bean能拿到ApplicationContext实例。这样Bean就可以在初始化时主动获取容器中的资源。面试官追问陷阱加分题追问1“BeanPostProcessor本身是一个Bean吗它自己会走生命周期吗”会。BeanPostProcessor本身也是由Spring容器管理的Bean它自己也会经历完整的生命周期——实例化、属性填充、初始化。但有一个关键点BeanPostProcessor的实例化会提前在普通Bean实例化之前就完成这样才能在普通Bean初始化时进行拦截处理。追问2“如果我在BeanPostProcessor.postProcessAfterInitialization()中返回了一个不同的对象比如代理对象会发生什么” 返回的对象会替换容器中原来的Bean实例。后续所有对这个Bean的依赖注入和getBean()调用拿到的都是这个新对象。这正是AOP的实现原理——Spring在postProcessAfterInitialization()中检查Bean是否需要切面增强如果需要就返回一个CGLIB或JDK动态代理对象替换掉原始Bean。追问3“Bean的销毁方法在什么情况下不会被调用” ①容器非正常关闭如kill -9强制杀死进程②原型prototype作用域的Bean容器不负责销毁③单例Bean如果从未被使用懒加载且没人调用也不会触发销毁。八、练习题简答题请按顺序说出Bean初始化的8个子步骤从Aware回调到BeanPostProcessor后置处理。代码题编写一个自定义BeanPostProcessor在Bean初始化前后打印日志并验证执行顺序。分析题某项目中Transactional注解不生效经过排查发现AOP代理没有创建。请分析可能的原因并给出解决方案。 你的学习进度当前第74篇 / 共108篇 ·进阶篇Spring全家桶第73~82篇✅ 已完成基础篇44篇 第45~74篇 正在学第74篇⏳ 待学习第75~108篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 下一篇文章预告下一篇《第75篇Spring AOP原理》内容简介AOP核心概念切面、通知、切入点、JDK动态代理 vs CGLIB、Transactional底层原理、切面执行顺序、AOP失效场景。Spring全家桶专题持续推进拿下AOP《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送
返回列表