spring源码之@Autowired属性注入

2023-11-04

注入现象

当我们在属性上面加上 @Autowired的时候,spring就要根据Type来注入实例了,那么到底会找哪个实例的如果有多个怎么办? 今天就来实验一下

多接口注入

当注入的属性接口下有多个实现。这个时候运行的话是


public class ModelTest {
	@Test
	public void defaultModel(){
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.scan("com.spring.inject");
		context.refresh();
		I i = context.getBean(F.class).getI();
		System.out.println("i==="+i);
	}
}

@Component
public class F {
	@Autowired
	I i;
	public I getI() {
		return i;
	}
}

public interface I {
}

@Component("a")
public class Ia implements I{
}

@Component("b")
public class Ib implements I{
}

报错如下:找到了多个实现接口类,不知道用哪个。
在这里插入图片描述

多接口制定名称注入

如果把F类中的属性名称指定。

@Component
public class F {
	@Autowired
	I a;
	public I getI() {
		return a;
	}
}

成功运行,注入了指定名称的Ia实例。
在这里插入图片描述

现象总结

Autowired是通过Type来寻找类的,如果找到多个实现,则再按照名称来寻找指定的类,最终确定一个类,注入到属性中。
下面我们来通过源码验证一下这个结论。

源码

点击Autowired进入该类,发现没有什么东西;但是类头部的注解让我们跳转这个类AutowiredAnnotationBeanPostProcessor,这明显就是Autowired的处理器。
在这里插入图片描述
这个类中有两个主要方法
AutowiredFieldElement和AutowiredMethodElement,意思是Autowired注解是在属性上和方法上。我们要看得肯定是第一个AutowiredMethodElement.inject()这个方法
红框的上半部分是缓存,如果解析过一次的话会走上面。我们主要看红框下半部分resolveMethodArguments方法。看这个方法名字就很清晰了,解析属性值,解析什么属性值呢,肯定是加了Autowired注解的属性。

在这里插入图片描述

DependencyDescriptor是一个依赖描述器,比如刚才例子中,会说明是在F类中的I属性上有这个Autowired注释,属性的名字是a等等数据。
然后通过这个依赖描述器,到beanFactory.resolveDependency()这个方法中进行处理。
在这里插入图片描述
这个方法中也有好多内容,现在可以先不用管,后面会慢慢分析那些懒加载之类的东西。只需要看doResolveDependency()这个方法。
在这里插入图片描述
这个方法中的这一行比较重要,是获取到多个属性的多个Bean之后直接注入到属性当中,不再按照名称筛选出单个。这也就是为什么当我们在List或者Map属性上加Autowired注释的时候,可以直接将接口下的所有实现类注入的原理。核心就是这个方法resolveMultipleBeans()。
这个方法中也简单就是判断一下Autowired注释下的属性是否是Array或者Map等数组集合类型,如果是的话,就将查询到的多个Bean直接塞进去返回,如果不是的话就返回一个空。
这里一旦返回一个空,就证明这个Autowired注释下的属性只能注入一个Bean。
在这里插入图片描述
顺着刚才的代码继续往下看,findAutowireCandidates()这个方法就是按照注释下的属性查找Bean。通过例子来解释的话,就是按照“I”这个类,查询到下面的两个实现类“Ia”和“Ib”。如果没有查询到的话就返回一个null。
下面还有一个判断如果查询到多个的话,就要进行筛选了。主要是通过这个方法determineAutowireCandidate()
在这里插入图片描述
可以看到,这个方法里面有个for循环,很简单嘛,意思就是通过属性的名字筛选多个Bean,如果名称一样的话,就返回对应的Bean。只要遍历到一个相同的就直接返回,因为在Spring中不可能有多个Bean的名字相同。
在这里插入图片描述

源码总结

  1. 当属性上有Autowired注解的时候
  2. 会先判断属性是否可以注入多个Bean,如果可以的话,直接将找到的多个注入进集合中
  3. 如果不可以的话,判断找到一个还是多个
  4. 找到一个Bean则直接返回
  5. 找到数量大于1个的话,将多个Bean遍历,与属性名称进行对比,一致则直接返回。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring源码之@Autowired属性注入 的相关文章

随机推荐

  • 多智能体强化学习入门(六)——MFMARL算法(Mean Field Multi-Agent RL)

    本节内容见https zhuanlan zhihu com p 56049023
  • lua 定时器以及应用

    function update timer fun for k v in pairs update timer m process time fun do v k update timer m porcess run time k end
  • qt操作excel表

    https blog csdn net cannon qi article details 79972258
  • day-37 代码随想录算法训练营(19)贪心part06

    738 单调递增的数字 思路 在给的数字中找到第一个开始递减的两个数字 将前一个数字减1 后面的数字全部变为最大值9 968 监控二叉树 思路 分三种状态 0无覆盖 1有监控 2有覆盖 分四种情况 1 两边都有覆盖 返回0 2 两边有一边无
  • 在关系数据库中。存放在数据库中的逻辑结构以什么为主 (4选一)

    C 哈希表
  • 笔试题2:如何用八进制和十六进制来表示整型数据

    八进制的含义在于每位数字的进位大小为8 也就是0 8的9个数字 十六进制的进位大小为16 除了0 9的10个数字 还包括a b c d e f来表示10 11 12 13 14 15 答案 Java的八进制采用0开头 十六进制采用0x开头
  • iOS宏定义的黑魔法 - 宏菜鸟起飞手册

    转自 OneV s Den的博客 宏定义在C系开发中可以说占有举足轻重的作用 底层框架自不必说 为了编译优化和方便 以及跨平台能力 宏被大量使用 可以说底层开发离开define将寸步难行 而在更高层级进行开发时 我们会将更多的重心放在业务逻
  • 计算机虚拟化+网络

    计算机虚拟化 网络 cookie 什么是 Cookie cookie的生命周期 cookie Cookie 用于存储 web 页面的用户信息 什么是 Cookie Cookie 是一些数据 存储于你电脑上的文本文件中 当 web 服务器向浏
  • C++像素游戏

    我的作品 鼠标板 黑科技之橡素 代码 include
  • Verilog语言实现FPGA上的计数器

    Verilog语言实现FPGA上的计数器 计数器是数字电路中经常使用的基本元素之一 它用于生成指定脉冲数量或者指定计数范围内的计数信号 在现代数字电路设计中 FPGA Field Programmable Gate Array 作为一种可编
  • QT+Opencv 时报错Failed to load module “canberra-gtk-module“

    解决方案 sudo apt get install libcanberra gtk module
  • 二维数组作为参数,传入函数(最好用的)

    二维数组作为参数 传入函数 最好用的 很多时候我都是直接通过传入一个 固定的数字来传递一个二维数组 比如这样子定义函数 int fun int a 3 int n 调用函数是 fun a n 这样子调用的二维数组只能是固定已经知道的 不够灵
  • 使用Kettle实现数据排序

    一 Kettle的安装 1 下载Kettle的安装包文件 在Windows系统中打开浏览器 访问Kettle官网 https sourceforge net projects pentaho 下载Kettle安装文件pdi ce 9 1 0
  • 最大公约数、最小公倍数、辗转相除法的求解和证明

    两个正整数的最大公约数 Greatest Common Divisor GCD 在计算机中通常使用辗转相除法计算 最小公倍数 Least Common Multiple LCM 可以使用GCD来计算 下面首先介绍GCD和LCM 然后介绍辗转
  • node.js解析xml(xmlreader)

    博客搬家 由于各种原因 我现在的博客将首发于blog mojijs com 可以百度搜索 姜哥的墨迹技术博客 或者 点击这里 本文地址 http blog mojijs com post 19 html xml作为一种重要的数据交换格式 我
  • 图书库毕业设计网页增删改查源码

    介绍 使用HTML VUE PHP MYSQL写的一个简单图书库 实现了简单的数据库增删改查 以及数据列表的展示 源码里包含了前端文件 和api文件 还有数据库表文件 搭建好环境 导入数据库 配置好数据库链接即可直接运行 学习资料地址 ht
  • javaswing基本使用

    package exam test1 import javax swing import java awt import java awt event ActionEvent import java awt event ActionList
  • 三态门——概念,作用,原理

    介绍一下三态门的概念 作用 原理 目录 三态门的概念 三态门的作用 实现总线结构 实现双向数据传输 三态门的原理 三态门的概念 三态门是指逻辑门的输出有三种状态 高电平状态 低电平状态 高阻状态 其中 高阻状态相当于隔离状态 因为高阻状态电
  • linux x64 asm 参数传递,x64 ASM 常用汇编指令

    语法习惯 立即数 开头 寄存器 开头 取地址里面的值 偏移量 寄存器 除了 lea 取地址指令 外 lea就是取地址 load effecive address 整形操作通用后缀 后缀 b w l q 1 2 4 8 byte word l
  • spring源码之@Autowired属性注入

    注入现象 当我们在属性上面加上 Autowired的时候 spring就要根据Type来注入实例了 那么到底会找哪个实例的如果有多个怎么办 今天就来实验一下 多接口注入 当注入的属性接口下有多个实现 这个时候运行的话是 public cla