Spring 源码系列(7): Bean 生命周期:实例化 → 属性填充 → 初始化 → 销毁
引子面试经典题“说一下 Spring Bean 的生命周期。”多数回答只到实例化、初始化漏掉三块关键内容①Aware接口回调的精确时机②PostConstruct与init-method的先后顺序③销毁阶段PreDestroy/DisposableBean/destroy-method。本篇把从new到destroy的完整链路补全并给出可背的九步法。一句话结论完整生命周期 实例化 → 提前暴露 → 属性填充 → Aware 回调 → BPP 前置(PostConstruct) →InitializingBean/init-method → BPP 后置(AOP) →可用→ 销毁(PreDestroy/DisposableBean/destroy-method)。注意ApplicationContextAware不在invokeAwareMethods里它由ApplicationContextAwareProcessorBPP注入。前置知识本篇是上一篇initializeBean的横向展开创建三段实例化/填充已在第 6 篇讲清。initializeBean只覆盖初始化这一段销毁由容器关闭时独立触发。只有单例Bean 的生命周期被容器完整管理原型prototypeBean 容器只负责创建到初始化销毁不归容器管。一、生命周期九步全景阶段触发点对应接口 / 注解① 实例化createBeanInstance构造器反射② 提前暴露addSingletonFactory仅单例解决循环依赖③ 属性填充populateBeanAutowired/Resource/property④ Aware 回调invokeAwareMethodsBeanNameAware/BeanFactoryAware/BeanClassLoaderAware⑤ BPP 前置applyBeanPostProcessorsBeforeInitializationPostConstruct⑥ 初始化方法invokeInitMethodsInitializingBean.afterPropertiesSet 自定义init-method⑦ BPP 后置applyBeanPostProcessorsAfterInitializationAOP 代理在此生成⑧ 就绪可用——返回最终对象可能是代理⑨ 销毁DisposableBeanAdapter.destroyPreDestroy/DisposableBean.destroy/ 自定义destroy-method⚠️易错点ApplicationContextAware、EnvironmentAware、MessageSourceAware等不在④ 的invokeAwareMethods里。它们由ApplicationContextAwareProcessor一个BeanPostProcessor在第 5 篇第 3 步注册在 ⑤ BPP 前置阶段注入。所以所有 Aware 都在初始化前这句话不严谨——要分清BeanFactory 级 Aware和ApplicationContext 级 Aware。二、初始化阶段源码invokeAwareMethods只认三个 BeanFactory 级接口privatevoidinvokeAwareMethods(StringbeanName,Objectbean){if(beaninstanceofAware){if(beaninstanceofBeanNameAware){((BeanNameAware)bean).setBeanName(beanName);}if(beaninstanceofBeanClassLoaderAware){((BeanClassLoaderAware)bean).setBeanClassLoader(getBeanClassLoader());}if(beaninstanceofBeanFactoryAware){((BeanFactoryAware)bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}initializeBean把 ④⑤⑥⑦ 串起来protectedObjectinitializeBean(StringbeanName,Objectbean,RootBeanDefinitionmbd){invokeAwareMethods(beanName,bean);// ④ObjectwrappedBeanbean;wrappedBeanapplyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);// ⑤ PostConstructinvokeInitMethods(beanName,wrappedBean,mbd);// ⑥wrappedBeanapplyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);// ⑦ AOPreturnwrappedBean;}invokeInitMethods的顺序先InitializingBean.afterPropertiesSet再自定义init-methodprotectedvoidinvokeInitMethods(StringbeanName,Objectbean,RootBeanDefinitionmbd){if(beaninstanceofInitializingBean){((InitializingBean)bean).afterPropertiesSet();// 接口优先}if(mbd!nullStringUtils.hasLength(mbd.getInitMethodName())){invokeCustomInitMethod(beanName,bean,mbd.getInitMethodName());// init-method 在后}}三、销毁阶段源码容器关闭close()时DisposableBeanAdapter.destroy()按以下顺序执行PreDestroy标注的方法由CommonAnnotationBeanPostProcessor注册为DestructionAwareBeanPostProcessorDisposableBean.destroy()接口自定义destroy-methodXML/Bean(destroyMethod)。结论销毁顺序与初始化对称——注解PreDestroy优先于接口DisposableBean优先于自定义方法destroy-method。四、生命周期流程图五、常见误区误区正解PostConstruct属于init-method否它走 BPP 前置PostConstruct是 JSR-250init-method是InitializingBean之后的自定义方法ApplicationContextAware在invokeAwareMethods注入否由ApplicationContextAwareProcessorBPP在初始化前置阶段注入原型 Bean 也有销毁回调否容器不管理原型 Bean 的销毁需自行释放InitializingBean比init-method先执行是接口优先于自定义方法六、面试题自测完整生命周期按什么顺序至少说出 7 个关键节点。BeanNameAware/BeanFactoryAware/ApplicationContextAware分别在何时注入PostConstruct、InitializingBean.afterPropertiesSet、init-method三者执行顺序销毁阶段的执行顺序是什么为什么原型prototypeBean 的PreDestroy不生效七、Debug 小技巧在initializeBean第一行打断点Step IntoinvokeAwareMethods确认只有三个 BeanFactory 级 Aware 被回调。在applyBeanPostProcessorsBeforeInitialization处观察传入的是原始对象走完PostConstruct才返回若被 AOP 代理最终返回的是代理类。验证销毁在测试末尾调用((ConfigurableApplicationContext) ctx).close()在DisposableBeanAdapter.destroy打断电看三个销毁动作的执行次序。下篇预告第 8 篇我们回头钻populateBean阶段依赖注入DI在源码里如何发生——Autowired/Resource到底在哪一步、怎么把依赖对象塞进字段。如果这篇对你有帮助欢迎点赞 · 收藏 · 关注三连支持。Spring 源码系列共 30 篇由浅入深持续更新中。有疑问或想深挖的源码点评论区告诉我下篇见。

相关新闻

DFN、SOT23-6还是SOP8?认证芯片封装也会影响量产落地

DFN、SOT23-6还是SOP8?认证芯片封装也会影响量产落地

安全芯片选型时,工程师容易把注意力全部放在安全功能上,直到进入PCB设计和试产阶段,才发现封装尺寸、焊接能力、检测方式与返修条件同样会影响项目。封装没有绝对优劣,关键是与产品空间、产线能力和生命周期阶段匹配。小型DFN适合…

2026/10/17 15:49:30 阅读更多 →
YOLOv13改进:AttnRes残差自注意力模块提升目标检测精度

YOLOv13改进:AttnRes残差自注意力模块提升目标检测精度

1. 项目概述今天要分享的是我们团队在YOLOv13目标检测模型上的一个重要改进——AttnRes残差自注意力模块。这个创新点已经在多个基准测试集上验证了其有效性,最高能带来2.3%的mAP提升。不同于传统的注意力机制,我们通过引入残差思想,有效解决…

2026/10/18 2:52:09 阅读更多 →
智能模型本质解析:从NAS-RL到MAPPO的技术实现

智能模型本质解析:从NAS-RL到MAPPO的技术实现

1. 项目概述:智能模型的本质探讨 "这是智能模型吗?"这个看似简单的问题背后,隐藏着对人工智能本质的深度思考。作为一名从业多年的AI工程师,我经常被问到类似的问题——当一个模型能够完成特定任务时,它是否…

2026/10/16 23:44:46 阅读更多 →

最新新闻

ESP32分区表完全指南:从partitions.csv到OTA与Flash规划

ESP32分区表完全指南:从partitions.csv到OTA与Flash规划

第一次打开ESP32工程目录,看到partitions.csv这个文件时,我压根没当回事,以为就是个自动生成的临时配置。直到有一次编译报错提醒我“app partition is too small”,我才被迫去搞懂它。搞懂之后回头看,分区表几乎决定了…

2026/10/18 7:30:04 阅读更多 →
SQL注入入门:从原理到实战,数字型与字符型详解(2)

SQL注入入门:从原理到实战,数字型与字符型详解(2)

摘要:本文以 SQL 注入为主题,先回顾数字型注入与字符型注入的区别,再重点讲解两个关键探测手段:order by 用于判断查询结果的列数,union 用于把自定义查询结果拼接到原查询后面。文章结合靶场实例,详细演示…

2026/10/18 7:30:04 阅读更多 →
UART串口实战:从寄存器配置到printf重定向的嵌入式调试指南

UART串口实战:从寄存器配置到printf重定向的嵌入式调试指南

1. 从Day1到Day3之后,我为什么决定把第四天留给串口说实话,我前三天是有点浮躁的。Day1搭建开发环境,Day2点亮板载LED,Day3用按键控制灯亮灭。做完这些之后我一度觉得嵌入式好像也就这么回事——配置几个寄存器、写几个while(1)循…

2026/10/18 7:30:04 阅读更多 →
仿muduo实现高并发服务器——读写缓冲区Buffer.hpp

仿muduo实现高并发服务器——读写缓冲区Buffer.hpp

目录摘要注释3.1 回顾3.2 新知识3.3 注意3.4 反思正文4.1 开发中遇到的问题总结常见问题标签摘要 Buffer.hpp 是 header-only 实现:#include 即用,无需链接 .cpp/.a/.so。内部为 std::vector 加 _redidx/_wrtidx 两个下标,提供写入、读取、容…

2026/10/18 7:30:04 阅读更多 →
随身WiFi的adb shell常用命令三十条:系统状态一键体检

随身WiFi的adb shell常用命令三十条:系统状态一键体检

本文是随身WiFi系列第 69 篇,正文约 3200 字,读完约 9 分钟。前面几十篇里散落过各种 adb 命令,评论区一直喊"有没有一个合集"。这篇把最常用的三十条按场景归档:看信号、看流量、看内存、看存储、看日志、救急&#xf…

2026/10/18 7:30:04 阅读更多 →
基于STM32H750与SOEM的EtherCAT主站开发实战解析

基于STM32H750与SOEM的EtherCAT主站开发实战解析

1. 为什么我最终选了"H750SOEM"这套组合做EtherCAT主站开发,绕不开一个问题:用哪颗芯片、跑哪套协议栈。市面上主流的方案分两派,一派走ASIC专用芯片,另一派走"MCU软件协议栈"。我这次选的是后者,…

2026/10/18 7:29:04 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →