Spring 源码系列(8): 依赖注入(DI)在源码里如何发生
引子你只写了Autowired private UserService userService;对象就自动出现了。这背后 Spring 到底做了什么本篇回答三件事① DI 发生在哪一步②Autowired和Resource的区别在源码层如何体现③字段 / 构造器 / setter 注入为何出生在不同阶段——这直接决定了第 9 篇循环依赖为何只有字段注入能解。一句话结论字段/setter 注入发生在populateBean阶段由AutowiredAnnotationBeanPostProcessor.postProcessProperties找到注入点经resolveDependency → getBean(依赖)递归拿到或创建依赖对象最后field.set注入。构造器注入则更早在createBeanInstance推断构造器时就解析依赖。前置知识DI 的本质是在合适时机把依赖对象 set 进当前 Bean。处理 DI 的是InstantiationAwareBeanPostProcessor一类特殊的BeanPostProcessorAutowiredAnnotationBeanPostProcessor处理Autowired/ValueCommonAnnotationBeanPostProcessor处理Resource/PostConstruct/PreDestroy这些 BPP 在第 5 篇第 6 步registerBeanPostProcessors被注册进容器。一、字段注入发生在 populateBean// AbstractAutowireCapableBeanFactory.populateBean精简protectedvoidpopulateBean(StringbeanName,RootBeanDefinitionmbd,BeanWrapperbw){// 遍历 InstantiationAwareBeanPostProcessor触发注入for(InstantiationAwareBeanPostProcessorbp:getBeanPostProcessors()){PropertyValuespvsbp.postProcessProperties(pvs,bw.getWrappedInstance(),beanName);// Autowired 就是在这一行完成的}// XML property 配置的值应用applyPropertyValues(beanName,mbd,bw,pvs);}二、AutowiredAnnotationBeanPostProcessor 如何注入postProcessProperties→ 找注入点 → 逐个注入// AutowiredAnnotationBeanPostProcessorpublicPropertyValuespostProcessProperties(PropertyValuespvs,Objectbean,StringbeanName){// 1. 取出缓存的注入元数据Autowired 字段/方法InjectionMetadatametadatafindAutowiringMetadata(beanName,bean.getClass());// 2. 逐个注入metadata.inject(bean,beanName,pvs);returnpvs;}注入一个字段时AutowiredFieldElement.injectprotectedvoidinject(Objectbean,StringbeanName,PropertyValuespvs){Fieldfieldthis.field;ObjectvalueresolveFieldValue(field,bean,beanName);// ← 关键解析依赖ReflectionUtils.makeAccessible(field);field.set(bean,value);// 反射设值}resolveFieldValue最终会走到DefaultListableBeanFactory.resolveDependencyresolveFieldValue └─ beanFactory.resolveDependency(descriptor, beanName, ...) └─ doResolveDependency(...) ├─ 按类型找到候选 Bean可能有多个再按 Qualifier / 名称筛选 └─ resolveCandidate(beanName, ...) └─ beanFactory.getBean(beanName) // ← 递归依赖没创建就先创建它⚠️关键getBean(依赖)这一行就是依赖注入的本质——也是循环依赖产生的根源A 注入 BB 又注入 A二者互相等待。第 9 篇专门解决它。三、Autowired vs Resource维度AutowiredResource来源Spring 自带org.springframework.beans.factory.annotationJSR-250 标准javax.annotation默认匹配按类型byType**按名称byName**优先失败再 byType配合限定Qualifier(name)指定名称name属性直接指定必需性required属性默认 true无 required找不到直接报错处理类AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor四、三种注入方式的出生阶段注入方式发生在哪源码位置能否解循环依赖字段注入populateBeanAutowiredFieldElement.inject✅ 能靠三级缓存setter 注入populateBeanAutowiredMethodElement.inject✅ 能构造器注入createBeanInstancedetermineCandidateConstructors 构造时getBean依赖❌ 不能为什么构造器注入不能解循环依赖构造器注入在createBeanInstance实例化阶段就要求依赖对象已经存在而此时当前 Bean 还没执行到addSingletonFactory三级缓存注册依赖方取不到提前暴露的引用只能再去创建当前 Bean形成无限递归 →BeanCurrentlyInCreationException。五、DI 流程图六、常见误区误区正解Autowired按名称注入默认按类型需配合Qualifier才按名称Resource是 Spring 注解是 JSR-250 标准注解由CommonAnnotationBeanPostProcessor处理构造器注入也能解循环依赖不能见上文DI 发生在initializeBean字段/setter 注入在populateBean早于初始化七、面试题自测Autowired在 Bean 生命周期的哪一步注入resolveDependency最终调用了什么方法创建依赖Autowired与Resource的核心区别字段、setter、构造器三种注入分别发生在哪个阶段为什么只有前两种能解循环依赖有多个同类型 Bean 时Autowired如何筛选出目标提示Qualifier/ 优先级八、Debug 小技巧在AutowiredAnnotationBeanPostProcessor.postProcessProperties打断电Step Intometadata.inject→resolveFieldValue看value是如何从getBean拿到的。故意制造循环依赖A 构造器注入 BB 构造器注入 A观察异常栈最顶端是BeanCurrentlyInCreationException且发生在createBeanInstance阶段。在resolveCandidate的getBean处打条件断点beanName.equals(依赖名)验证注入即触发依赖的创建。下篇预告第 9 篇爆款预定循环依赖终极拷问——为什么用三级缓存而不是二级。把本篇埋下的getBean递归与提前暴露彻底讲透。如果这篇对你有帮助欢迎点赞 · 收藏 · 关注三连支持。Spring 源码系列共 30 篇由浅入深持续更新中。有疑问或想深挖的源码点评论区告诉我下篇见。

相关新闻

iPhone17护眼钢化膜避坑:悟赫德拆解四大套路

iPhone17护眼钢化膜避坑:悟赫德拆解四大套路

iPhone17护眼钢化膜避坑指南:2026年这四大套路别再信了新买的iPhone 17到手,第一张膜往往踩坑最多。市面上关于“护眼钢化膜”的说法五花八门,蓝光膜、绿光膜、紫光膜,每个都声称自己护眼,但真正用起来不是偏色就是反光…

2026/10/17 7:41:25 阅读更多 →
栈在表达式中求值的应用(中缀表达式的结算机算——用栈实现)

栈在表达式中求值的应用(中缀表达式的结算机算——用栈实现)

文章目录中缀表达式 转 后缀表达式(机算,用栈实现)中缀表达式的机算(用栈实现)中缀表达式 转 后缀表达式(机算,用栈实现) 初始化一个栈,用于保存暂时还不能确定运算顺序…

2026/10/17 7:41:44 阅读更多 →
从 Qwen-2.5 到 Qwen-4:企业级后端集成架构的代际跨越与兼容性重构

从 Qwen-2.5 到 Qwen-4:企业级后端集成架构的代际跨越与兼容性重构

从 Qwen-2.5 到 Qwen-4:企业级后端集成架构的代际跨越与兼容性重构上周处理一个遗留的订单服务时,我们遇到了严重的上下文截断导致的逻辑错误。虽然通过增加重试机制勉强稳住,但那种“把大模型当黑盒调”的粗糙感让我意识到,随着通…

2026/10/17 7:44:40 阅读更多 →

最新新闻

Excel数据透视表实战:从源数据清洗到动态汇总的完整指南

Excel数据透视表实战:从源数据清洗到动态汇总的完整指南

简介:这份《Excel数据透视表应用大全》面向需要处理大量业务数据的职场人士与Excel进阶学习者,帮助解决多维度汇总、分类比较与百分比分析等实际分析难题。资源以Word文档形式呈现,共1个doc文件,压缩包约10MB,内容围绕…

2026/10/17 16:16:28 阅读更多 →
糖尿病预测项目实战:从Jupyter Notebook到完整机器学习建模链路

糖尿病预测项目实战:从Jupyter Notebook到完整机器学习建模链路

简介:这是一套以 Jupyter Notebook 为核心的糖尿病预测入门项目,面向机器学习初学者与数据分析爱好者,演示如何利用 Pima Indians Diabetes 数据集完成从数据清洗、EDA 可视化、特征工程到模型训练与评估的完整流程。压缩包共 4 个文件、约 3…

2026/10/17 16:16:28 阅读更多 →
UML建模实战:校园图书管理系统需求分析与代码生成全解析

UML建模实战:校园图书管理系统需求分析与代码生成全解析

简介:在软件工程实践中,需求分析是决定系统质量的关键环节,而UML建模为需求到设计的转化提供了标准语言。通过用例图明确参与者与功能边界,利用类图梳理实体关系,再借助顺序图推演业务流程,这一系列静态与动…

2026/10/17 16:16:28 阅读更多 →
React入门笔记:组件化、JSX与Hooks实战指南

React入门笔记:组件化、JSX与Hooks实战指南

磨蹭了很久,终于开始系统性梳理React的学习笔记了。前端框架用了不少,但每次都是照着文档敲,敲完就忘,这次决定用"写笔记"的方式逼自己把原理层面的东西弄透。这篇笔记是第一阶段的内容,从组件化思想、JSX语法、状态管理到Hooks的基本用法,全部基于我实际敲代码时的理…

2026/10/17 16:16:28 阅读更多 →
GA-LSTM:用遗传算法自动搜索LSTM超参数,告别手动调参

GA-LSTM:用遗传算法自动搜索LSTM超参数,告别手动调参

简介:基于遗传算法优化LSTM的Python实现资源,面向需要提升时间序列预测准确率的深度学习开发者与研究人员。项目将GA全局搜索能力与LSTM序列建模优势结合,通过GA自动寻优LSTM权重、偏置等参数,缓解传统RNN梯度消失问题&#xff0c…

2026/10/17 16:16:28 阅读更多 →
MySQL学生成绩管理系统数据库设计:需求分析、建表、视图与存储过程完整方案

MySQL学生成绩管理系统数据库设计:需求分析、建表、视图与存储过程完整方案

简介:这份资源是北邮研一数据库课程大作业的完整详解文档,面向正在修读数据库系统课程、需要完成课程设计的研究生及高年级本科生。内容围绕学生成绩管理系统展开,覆盖需求分析、数据库设计、ER图绘制、逻辑结构设计与建表程序等完整流程&…

2026/10/17 16:15:27 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →