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/8/10 10:22:24 阅读更多 →
栈在表达式中求值的应用(中缀表达式的结算机算——用栈实现)

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

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

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

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

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

2026/8/11 1:13:10 阅读更多 →

最新新闻

GLINK通信中间件:面向高并发长连接场景的高性能解决方案

GLINK通信中间件:面向高并发长连接场景的高性能解决方案

1. 从一次“通信失败”的排查说起那天下午,我正盯着监控面板上一条不断跳动的告警信息发愁。告警来自一个部署在边缘设备上的数据采集模块,它负责将传感器数据上报到云端。日志里反复出现“连接建立失败”和“资源不足”的错误。这个模块基于一个常见的开…

2026/8/13 5:05:33 阅读更多 →
Windows PIN登录失效的深度诊断与修复指南

Windows PIN登录失效的深度诊断与修复指南

1. 项目概述:当Windows PIN突然“罢工”时你有没有遇到过这样的场景:早上到公司,或者刚重启完电脑,准备用PIN码快速登录Windows系统,结果屏幕上赫然显示“你的PIN不可用,请使用密码登录”?那一刻…

2026/8/13 5:05:33 阅读更多 →
AI文本水印技术解析:从绿名单算法到工程实践

AI文本水印技术解析:从绿名单算法到工程实践

最近在部署和使用各类AI模型时,你是否遇到过这样的困惑:如何判断一段文本是AI生成的还是人类创作的?随着AI生成内容(AIGC)的爆炸式增长,这个问题正变得日益尖锐。无论是学术诚信、内容版权,还是…

2026/8/13 5:05:33 阅读更多 →
C++ RAII与智能指针:从资源管理困境到现代编程实践

C++ RAII与智能指针:从资源管理困境到现代编程实践

1. 项目概述:从资源管理的“泥潭”到RAII的“救赎”如果你写过一段时间的C,尤其是写过一些需要手动管理内存、文件句柄或者网络连接这类资源的代码,那你大概率经历过这样的深夜:程序运行了几个小时后突然崩溃,或者内存…

2026/8/13 5:05:33 阅读更多 →
IHP SG13G2开源PDK:130nm BiCMOS工艺设计套件的深度技术解析与应用实践

IHP SG13G2开源PDK:130nm BiCMOS工艺设计套件的深度技术解析与应用实践

IHP SG13G2开源PDK:130nm BiCMOS工艺设计套件的深度技术解析与应用实践 【免费下载链接】IHP-Open-PDK 130nm BiCMOS Open Source PDK, dedicated for Analog, Mixed Signal and RF Design. Documentation is here: 项目地址: https://gitcode.com/gh_mirrors/ih/…

2026/8/13 5:05:33 阅读更多 →
Windows开机密码忘记?PE启动盘重置密码全攻略

Windows开机密码忘记?PE启动盘重置密码全攻略

1. 问题场景与核心思路剖析遇到电脑开机密码忘记的情况,相信不少朋友都心头一紧。无论是个人电脑还是工作用机,这扇“门”一旦打不开,里面的文件、资料、正在进行的工作都可能被暂时锁住,确实让人着急。尤其是现在很多朋友习惯用微…

2026/8/13 5:04:33 阅读更多 →

日新闻

Visual Studio新建项目解决方案为空:系统性排查与修复指南

Visual Studio新建项目解决方案为空:系统性排查与修复指南

1. 问题现象与本质剖析如果你是一位.NET开发者,或者正准备踏入这个领域,那么Visual Studio(后面简称VS)绝对是你绕不开的伙伴。但有时候,这个伙伴会跟你开一个不大不小的玩笑:你满怀期待地点击“创建新项目…

2026/8/13 0:00:09 阅读更多 →
长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

说实话,每次提起“长春建设厅网站”这几个字,我心里都挺有感触的。不是因为它有多高大上,也不是因为那里藏着什么不可告人的秘密,恰恰相反,是因为它太“接地气”了,或者说,它是咱们普通人想要在这个城市好好生活、安稳买房时,必须得翻过的一座“数据山”。很多新朋友第…

2026/8/13 0:00:09 阅读更多 →
Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾为Windows家庭版无法支持多用户远程桌面…

2026/8/13 0:00:09 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/12 1:11:09 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/12 1:11:08 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/11 17:09:45 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/12 1:11:10 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/11 17:09:45 阅读更多 →