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/7/22 12:04:54 阅读更多 →
YOLOv13改进:AttnRes残差自注意力模块提升目标检测精度

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

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

2026/7/22 12:04:54 阅读更多 →
智能模型本质解析:从NAS-RL到MAPPO的技术实现

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

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

2026/7/23 12:25:16 阅读更多 →

最新新闻

【AI大模型】思维链提示:CoT让模型推理能力直接翻倍

【AI大模型】思维链提示:CoT让模型推理能力直接翻倍

【AI大模型】思维链提示:CoT让模型推理能力直接翻倍(含实操代码) 在AI大模型提示词工程体系中,绝大多数用户都会遇到同一个核心难题:大模型处理复杂推理、逻辑计算题、多层级分析问题时,经常出现步骤跳脱、逻辑断层、答案出错、想当然结论等问题。哪怕使用高精度大模型,…

2026/7/24 14:34:04 阅读更多 →
VR一体机全局菜单开发:Android输入拦截与Unity 3D渲染的跨进程架构

VR一体机全局菜单开发:Android输入拦截与Unity 3D渲染的跨进程架构

1. 项目概述:VR一体机全局菜单的进阶挑战在VR一体机的系统开发中,全局菜单是一个标志性的用户体验组件。它不同于手机上的状态栏或导航栏,需要悬浮在3D空间里,随时响应头戴设备的姿态和用户的操作意图,并且不能干扰正在…

2026/7/24 14:34:04 阅读更多 →
Agent中的向量数据库选型:Milvus、Qdrant与Weaviate的创业场景对比

Agent中的向量数据库选型:Milvus、Qdrant与Weaviate的创业场景对比

Agent中的向量数据库选型:Milvus、Qdrant与Weaviate的创业场景对比 一、RAG架构下的向量检索瓶颈 Agent系统的核心能力之一,是通过RAG(检索增强生成)获取外部知识。向量数据库作为RAG的检索层,其性能直接决定了Agent的…

2026/7/24 14:34:04 阅读更多 →
创业团队的技术债代码重构:一次历时三个月的架构升级全记录

创业团队的技术债代码重构:一次历时三个月的架构升级全记录

创业团队的技术债代码重构:一次历时三个月的架构升级全记录 一、技术债从隐性成本到显性危机 创业公司在早期为了快速验证产品,必然会在代码质量上做出妥协。这种妥协在用户量突破十万、日活突破一万之前,几乎不会引发实质性问题。一旦业务开…

2026/7/24 14:34:04 阅读更多 →
用做菜类比RAG架构:食材准备、配方检索与火候控制的形象解释

用做菜类比RAG架构:食材准备、配方检索与火候控制的形象解释

用做菜类比RAG架构:食材准备、配方检索与火候控制的形象解释 一、为什么RAG需要一个食物类比 "RAG(检索增强生成)是在LLM推理前从外部知识库检索相关信息并注入上下文"——这个技术定义对非技术读者来说毫无画面感。在一个面向产…

2026/7/24 14:34:04 阅读更多 →
Unity 7升级指南:无缝迁移、Beta测试价值与团队实践

Unity 7升级指南:无缝迁移、Beta测试价值与团队实践

如果你是一名 Unity 开发者,最近可能已经注意到了官方发布的重磅消息:Unity 7 即将到来,而且最关键的是——它承诺能够无缝继承 Unity 6 项目。这意味着什么?简单来说,你不需要为了升级而重写大量代码或调整项目结构。…

2026/7/24 14:33:03 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值,并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻