Spring-依赖注入的处理过程
前置知识
1 入口 DefaultListableBeanFactory#resolveDependency
2 每个依赖都有对应的DependencyDescriptor
3 自定绑定候选对象处理器AutowireCapableBeanFactory
注入处理
我们可以看到接口AutowireCapableBeanFactory中有两个方法。
第一个是单个注入:
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
还有一个是Set集合注入:
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
我们可以看到它的实现关系:

下面这个代码从IOC中查找并注入一个Bean,依据这个区跟踪一下源码:
public class AnnotationDependencyInjectResolutionDemo {@Autowiredprivate Person person;public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(AnnotationDependencyInjectResolutionDemo.class);context.refresh();QualifierAnnotationDependencyInjectDemo bean = context.getBean(QualifierAnnotationDependencyInjectDemo.class);}}
我们直接断点看一下DefaultListableBeanFactory#resolveDependency

DependencyDescriptor参数里面的信息:

DependencyDescriptor 描述了我们要注入的目标的一些信息:
参考文章:https://blog.csdn.net/andy_zhang2007/article/details/88135669
// 保存所包装依赖(成员属性或者成员方法的某个参数)所在的声明类,
// 其实该信息在 field/methodParameter 中已经隐含
private final Class<?> declaringClass;
// 如果所包装依赖是成员方法的某个参数,则这里记录该成员方法的名称
@Nullable
private String methodName;
// 如果所包装的是成员方法的某个参数,则这里记录该参数的类型
@Nullable
private Class<?>[] parameterTypes;
// 如果所包装的是成员方法的某个参数,则这里记录该参数在该函数参数列表中的索引
private int parameterIndex;
//如果所包装的是成员属性,则这里记录该成员属性的名称
@Nullable
private String fieldName;
// 标识所包装依赖是否必要依赖
private final boolean required;
// 标识所包装依赖是否需要饥饿加载
private final boolean eager;
// 标识所包装依赖的嵌套级别
private int nestingLevel = 1;
// 标识所包装依赖的包含者类,通常和声明类是同一个
@Nullable
private Class<?> containingClass;
// 所包装依赖 ResolvableType 的缓存
@Nullable
private transient volatile ResolvableType resolvableType;
// 所包装依赖 TypeDescriptor 的缓存
@Nullable
private transient volatile TypeDescriptor typeDescriptor;
下面分类去跟踪注入过程。
依赖查处理过程
1 普通的字段
@Configuration
public class LookUpByAnnotationSingle {@AutowiredPersonHolder personHolder;@Single@BeanPersonHolder personHolder(){Person person = new Person();person.setId(777L);person.setName("yong");return new PersonHolder(person);}public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(LookUpByAnnotationSingle.class);context.refresh();Object bean = context.getBean("personHolder");context.close();}
}
-
字段注入前面的判断都会跳过进入到下面这个方法

-
同样的我们只关注字段注入的核心流程,前面的条件都不满足来到这个方法findAutowireCandidates:

这个方法里面首先BeanFactoryUtils#beanNamesForTypeIncludingAncestors找到候选的Beans

候选的Bean是通过上面这个方法找到的,并且返回的时候将Bean对象放入到Map中。

然后我们如果我们多个bean,determineAutowireCandidate这个方法会决定一个Bean,决定的方式为如果使用了Primary就注入PrimaryBean否则Ordered根据这个接口定义(或者我们在Bean申明的时候标注了@Order注解)的优先级来寻找,数字越低优先级越高:

2 集合
@Autowired
private Collection<Person> personGroupAll;
集合注入核心逻辑会走到下面这个方法,这个方法返回的时候multipleBeans已经不为空了这个这个直接返回。

为什么上面可以直接返回呢,因为在resolveMultipleBeans方法中,判断了注入的类型如果是集合类型,也是走的一样的逻辑findAutowireCandidates找到候选的Bean进行返回。

3 懒加载
@Autowired
@Lazy
private Person person;
在懒注入的时候我们在这个方法已经有值了,所以逻辑在这一步就结束了,返回的是一个代理对象。

这个对象是cglib提升后的对象:

4 Optional
@Autowiredprivate Optional<Person> person;
核心逻辑是走下面

其实里面的逻辑是一样的,只是最后封装为Optional:

@Autowired注入过程
- 元信息解析
- 依赖查找
- 依赖注入(字段方法)
核心方法是AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement#inject,在注入的过程中会先去处理依赖也就是上面的流程:
参数bean是我们标注的类

这个方法被谁调用呢?属性后置处理AutowiredAnnotationBeanPostProcessor#postProcessProperties,当我们用xml配置的时候那么这个时候PropertyValues存储的就是的配置值

从打断点来看postProcessProperties方法会先于set注入执行,也就是先注入元信息,然后再注入值。
下面这个方法是合并子类和父类的元信息,每个类都会进入这个方法如果没有父类就是自己的元信息,这个方法在postProcessProperties之前执行。

这里会去查找AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

相关文章:
Spring-依赖注入的处理过程
前置知识 1 入口 DefaultListableBeanFactory#resolveDependency 2 每个依赖都有对应的DependencyDescriptor 3 自定绑定候选对象处理器AutowireCapableBeanFactory 注入处理 我们可以看到接口AutowireCapableBeanFactory中有两个方法。 第一个是单个注入: Null…...
2.用python爬取的保存在text文件中的格式为MP4的视频url
文章目录 一、url的保存格式二、MP4视频获取 一、url的保存格式 爬取的视频名字和url保存在text文件中,每一个视频都是一个单独的text,其中text的文件名就是视频的名字,text内容是视频的下载url,并且所有的text都保存在同一个文件…...
Java基于B/S医院绩效考核管理平台系统源码java+springboot+MySQL医院智慧绩效管理系统源码
Java基于B/S医院绩效考核管理平台系统源码javaspringbootMySQL医院智慧绩效管理系统源码 医院绩效考核系统是一个关键的管理工具,旨在评估和优化医院内部各部门、科室和员工的绩效。一个有效的绩效考核系统不仅能帮助医院实现其战略目标,还能提升医疗服…...
UE 蓝图堆栈调试
蓝图打断点后如果想查看断点前的执行逻辑,Tools→Debug→BlueprintDebugger 然后打断点运行,执行顺序是从下往上...
UE4_摄像机_使用摄像机的技巧
学习笔记,不喜勿喷!祝愿生活越来越好! 知识点: a.相机跟随。 b.相机抖动。 c.摄像机移动 d.四元数插值(保证正确旋转方向)。 e.相机注视跟踪。 1、新建关卡序列,并给小车添加动画。 2、创…...
ssm115乐购游戏商城系统+vue
毕业生学历证明系统 设计与实现 内容摘要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统毕业生学历信息管理难…...
【可实战】被测需求理解(需求文档是啥样的、从哪些角度进行需求评审、需求分析需要分析出哪些内容、如何提高需求分析能力)
产品人员会产出一个需求文档,然后组织一个需求的宣讲。测试人员的任务就是在需求宣讲当中,分析需求有没有存在一些问题,然后在需求宣讲结束之后通过分析需求文档,分析里面的测试点并预估一个排期。 一、需求文档是什么样的&#x…...
伪类和伪元素的区别是什么?
一、两者的定义 1.伪类(pseudo-class)是一个以冒号作为前缀,被添加到一个选择器末尾的关键字,当你希望样式在特定状态才被呈现到指定的元素时,你可以往元素的选择器后面加上对应的伪类。 2.伪元素用于创建一些不在文档…...
gorm-sharding分表插件升级版
代码地址: GitHub - 137/gorm-sharding: Sharding 是一个高性能的 Gorm 分表中间件。它基于 Conn 层做 SQL 拦截、AST 解析、分表路由、自增主键填充,带来的额外开销极小。对开发者友好、透明,使用上与普通 SQL、Gorm 查询无差别.解决了原生s…...
MoviePy(Python音视频开发)
音视频基础帧率、码率、分辨率视频格式H.264和H.265视频压缩算法 Moviepy常见剪辑类VideoFlieClipImageFlieClipColorClipTextClipCompositeVideoClipAudioFlieClipCompositeAudioClip 常见操作音视频的读入与导出截取音视频 音视频基础 帧率、码率、分辨率 体积(V…...
Spring中的FileCopyUtils:文件复制的利器与详解
1. 概述 在Spring框架中,FileCopyUtils是一个用于文件复制操作的实用工具类。它提供了一系列静态方法,简化了文件从输入流到输出流、从文件到文件等的复制过程。这些方法都基于NIO(New I/O)技术,提供了高效的文件复制…...
【操作系统】读者—写者问题python解析
一个数据问价或记录可以被多个进程共享,我们把只读该文件的进程称为“读者进程”,其他进程为“写者进程”。允许多个进程同时读一个共享对象,但不允许一个写者进程和其他写者进程或读者进程同时访问共享对象。即:保证一个写者进程…...
【driver5】调用堆栈函数,printk,动态打印,ftrace,proc,sysfs
文章目录 1.内核函数调用堆栈:4个函数2.printk:cat /proc/cmdline查看consolettyS03.动态打印:printk是全局的且只能设打印等级,动态打印可控制选择模块的打印,在内核配置打开CONFIG_DYNAMIC_DEBUG4.top&perf&…...
计算机毕业设计springboot基于vue电商抢购限时秒杀系统ch0h8
技术栈 ide工具:IDEA 或者eclipse 编程语言: java 数据库: mysql5.7以上版本 可选框架:ssmspringboot都有的 前端:vue.jsElementUI 详细技术:springbootSSMvueMYSQLMAVEN 数据库工具:Navicat/SQLyog都可以 开发工具 Ec…...
顺序表的实现(迈入数据结构的大门)(2)
目录 顺序表的头插(SLPushFront) 此时:我们有两个思路(数组移位) 顺序表的头删(学会思维的变换)(SLPopFront) 顺序表的尾插(SLPushBack) 有尾插就有尾删 既然头与尾部的插入与删除都有,那必然少不了指定位置的插入删除 查找…...
学习笔记:IEEE 1003.13-2003【POSIX PSE51接口列表】
一、POSIX PSE51接口列表 根据IEEE 1003.13-2003,整理了POSIX PSE51接口API(一共286个),每个API支持链接查看。详细内容参考下面表格: SN Module/_POSIX_宏 Function File 1 POSIX_C_LANG_JUMP(2) longjmp() &…...
《QT实用小工具·五十》动态增删数据与平滑缩放移动的折线图
1、概述 源码放在文章末尾 该项目实现了带动画、带交互的折线图,包含如下特点: 动态增删数值 自适应显示坐标轴数值 鼠标悬浮显示十字对准线 鼠标靠近点自动贴附 支持直线与平滑曲线效果 自定义点的显示类型与大小 自适应点的数值显示位置 根据指定锚点…...
【qt】核心机制信号槽(下)
这里写目录标题 自定义的信号自定义的槽自定义的信号和槽的结合使用信号和槽的断开总结: 自定义的信号 信号就是一个函数声明 前面咱们都用的qt组件自带的信号,接下来我们自己写一个信号。 信号只需要在前面加一个signals即可 这个函数不需要实现 参数传…...
C++ 基础 输入输出
一 C 的基本IO 系统中的预定义流对象cin和cout: 输入流:cin处理标准输入,即键盘输入; 输出流:cout处理标准输出,即屏幕输出; 流:从某种IO设备上读入或写出的字符系列 使用cin、cout这两个流对…...
八股文(C#篇)
C#中的数值类型 堆和栈 值类型的数据被保存在栈(stack)上,而引用类型的数据被保存在堆(heap)上,当值类型作为参数传递给函数时,会将其复制到新的内存空间中,因此在函数中对该值类型的修改不会影…...
在OpenClaw中快速接入Taotoken实现AI助手功能
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在OpenClaw中快速接入Taotoken实现AI助手功能 OpenClaw是一款功能强大的AI助手工具,能够帮助开发者进行代码生成、问题…...
终极指南:Task代码审查的10个质量控制最佳实践
终极指南:Task代码审查的10个质量控制最佳实践 【免费下载链接】task A fast, cross-platform build tool inspired by Make, designed for modern workflows. 项目地址: https://gitcode.com/gh_mirrors/ta/task Task作为一款受Make启发的现代化构建工具&am…...
告别金融数据壁垒:如何用AKTools一键打通多语言财经数据接口
告别金融数据壁垒:如何用AKTools一键打通多语言财经数据接口 【免费下载链接】aktools AKTools is an elegant and simple HTTP API library for AKShare, built for AKSharers! 项目地址: https://gitcode.com/gh_mirrors/ak/aktools 还在为不同编程语言获取…...
Obsidian Importer:一站式笔记数据迁移终极指南
Obsidian Importer:一站式笔记数据迁移终极指南 【免费下载链接】obsidian-importer Obsidian Importer lets you import notes from other apps and file formats into your Obsidian vault. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-importer …...
绝对不要让两根线在同一个交换机上连成一个圈。 为什么 形成一个环就会网络风暴?
为了让你彻底理解“为什么环路会导致风暴”,我们把网络连接看作一个“数字信息的传递游戏”。 1. 关键前提:交换机不懂“记忆” 交换机(特别是普通的傻瓜交换机)在转发广播消息时,它不具备判断“这条消息我刚才是不是发过”的能力。它只认一个逻辑: “只要是从端口A进来…...
从数据云到ArcGIS:一站式掌握DEM影像的获取、拼接与裁剪实战
1. DEM影像基础与数据源选择 数字高程模型(DEM)是地理信息系统中描述地表形态的基础数据,广泛应用于地形分析、水文模拟、工程建设等领域。对于刚接触GIS的朋友来说,最常见的困惑就是:从哪里获取DEM数据?不…...
告别手动填坑:用SSC工具+Excel快速搞定LAN9252 EtherCAT从站XML配置(附64点IO实例)
高效配置LAN9252 EtherCAT从站的自动化工具链实践 在嵌入式工业通信领域,EtherCAT因其卓越的实时性能被广泛采用,而LAN9252作为高性价比的从站控制器芯片,配合SPI接口成为许多开发者的首选方案。然而传统XML配置流程的复杂性往往成为项目瓶颈…...
OpenClaw从入门到应用——工具(Tools):Lobster
通过OpenClaw实现副业收入:《OpenClaw赚钱实录:从“养龙虾“到可持续变现的实践指南》 Lobster 是一个工作流 Shell,它让 OpenClaw 将多步工具序列作为单一的、确定性的操作来运行,并带有明确的审批检查点。 引子 你的助手可以…...
抖音无水印视频下载全攻略:douyin-downloader开源工具终极指南
抖音无水印视频下载全攻略:douyin-downloader开源工具终极指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallba…...
Boss-Key:Windows下一键隐藏窗口的终极隐私保护工具
Boss-Key:Windows下一键隐藏窗口的终极隐私保护工具 【免费下载链接】Boss-Key 老板来了?快用Boss-Key老板键一键隐藏静音当前窗口!上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在数字化办公时代…...
