Spring源码分析之依赖注入(二)2

简介: Spring源码分析之依赖注入(二)

怎么根据 Bean的类型去找

我们进入 getBeanNamesForType方法, 具体如下图所示

网络异常,图片无法展示
|

doGetBeanNamesForType方法

这个方法太长了, 而且我看着真的蒙, 简单讲一下流程, 感兴趣的话大家自己看一下:

  • 遍历 BeanDefinition
  • 判断bean名字前有没有&符号, 有的话去处理掉
  • 拿取 BeanDefinition的属性判断当前的是否匹配

网络异常,图片无法展示
|

返回

我们回到本方法的开头, 只要知道这个方法是从 BeanFactory中找出和 requiredType所匹配的 beanName, 仅仅是 beanName, 这些 bean不一定经过了实例化, 只有到最终确定某个 Bean了, 如果这个Bean还没有实例化才会进行实例化

网络异常,图片无法展示
|

resolvableDependencies

在 Spring启动的时候就会忘这个 map中存东西,

网络异常,图片无法展示
|
这个 map具体的存储过程如下图所示: 后续讲Spring启动源码的时候会讲

网络异常,图片无法展示
|

Bean对象加入到集合

然后去遍历这个 map, 获取到 key也就是 Bean类型, 判断有没有相同的 Bean类型, 如果有就把对应的对象加入到我们的返回数组中

网络异常,图片无法展示
|

遍历判断是不是自己注入自己

  • 如果不是自己注入自己,则判断该candidate到底能不能用来进行自动注入
  • 注入非自己
  • 如果有多个candidate 最终将匹配成功 candidate加入到 result
  • 因为有多个, 且result不为空
  • 所以直接返回 result

网络异常,图片无法展示
|

result.isEmpty()

  • 假设有多个 candidate, 且都不匹配, result == null
  • 则会去判断需要的类型是不是 Map, 数组之类的
  • 中间那个for循环用的很少 , 就先不看了
  • 如果匹配的是自己, 就将自己添加到result中

网络异常,图片无法展示
|

返回

然后去判断 如果没有找到 Bean则抛出异常

网络异常,图片无法展示
|

如果找到了多个 Bean

如图所示, 如果根据 beanName找到了多个 Bean那么该 if判断则为 true

网络异常,图片无法展示
|

determineAutowireCandidate方法

网络异常,图片无法展示
|
在这个方法中, 我们先去获取他的类型, 获取类型之后执行 determinePrimaryCandidate方法, 下图是这个方法的详情

网络异常,图片无法展示
|
上图中的方法经历了以下几个步骤:

  • 遍历 map获取对应的 beanName和 ( bean对象或 Class类)
  • isPrimary方法, 判断这多个 Bean有没有否实现了 @isPrimary注解
  • 如果都实现了 @isPrimary注解则抛出异常
  • 如果只有一个实现了  @isPrimary注解则使用这个 Bean

方法结束, 返回上一层 determineAutowireCandidate方法

网络异常,图片无法展示
|
途中红框部分的方法讲解完毕, 接下来它去寻找了我们的返回值, 如果都没有实现 @Primary注解, 那么继续往下走

determineHighestPriorityCandidate方法

方法流程如下:

  • 遍历map
  • 取当前某个Bean的优先级是什么
  • 获取 @Priority注解, 方法在下图红框位置

网络异常,图片无法展示
|

@Priority 该注解不能使用在方法上, 只能使用在类上面

@Order在依赖注入中是没有去使用判断的

方法结束, 返回上一层 determineAutowireCandidate方法

网络异常,图片无法展示
|
如上图所示, 我们继续往下走, 最后才是根据名字去判断 bean对象的

通过源码可以看到 @Resource 和 @Autowired的区别 如果有多个同名beanName, 那么@Autowired 会先去寻找有没有哪个 bean是有 @Primary注解的, 如果都没有, 则去寻找有没有哪个类上是有 @Priority优先级注解的, 如果都没有则会去按照名称查找 这个面试题在刚毕业的时候也是经常被问到的, 以前只知道答案, 这次通过源码对其的解答也更加清晰明了了

返回

接下来返回到下面红框的位置, 继续玩下走

如果没有找到对象, required == true抛出异常, 如果不为 true则返回 null, 然后赋值

网络异常,图片无法展示
|

如果只找到了一个 Bean

那么直接为之前定义的 autowiredBeanName 和 instanceCandidate进行赋值

如果找到了Bean

如果找到了Bean , 则进行记录

网络异常,图片无法展示
|

判断 instanceCandidate是不是一个类

如果是一个类, 那么获取这个类的 bean

网络异常,图片无法展示
|

去判断这个类型是不是 NullBean

NullBean的定义代码如下所示, 当以下面的方式定义一个 bean的时候, 这个bean存在 map中的 key为 JuejinService, value为 NullBean

@Bean
public JuejinService juejinService(){
   return null;
}
复制代码

相关判断代码如下所示

网络异常,图片无法展示
|

最后返回 over

最后红框判断的是期望类型和实际获取到的类型是否一致问题, 就不详细解释了

网络异常,图片无法展示
|

Spring专栏历史文章

目录
相关文章
|
3月前
|
XML Java 测试技术
Spring Boot中的依赖注入和控制反转
Spring Boot中的依赖注入和控制反转
|
5月前
|
XML Java 程序员
Spring6框架中依赖注入的多种方式(推荐构造器注入)
依赖注入(DI)是一种过程,对象通过构造函数参数、工厂方法的参数或在对象实例构建后设置的属性来定义它们的依赖关系(即与其一起工作的其他对象)。
78 3
|
5月前
|
Java 测试技术 开发者
Spring IoC容器通过依赖注入机制实现控制反转
【4月更文挑战第30天】Spring IoC容器通过依赖注入机制实现控制反转
50 0
|
2月前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
35 0
|
2月前
|
设计模式 自然语言处理 Java
简单了解下Spring中的各种Aware接口实现依赖注入
在Spring框架中,Aware接口是一组用于提供特定资源或环境信息的回调接口。这些接口被设计用来允许Bean获取对Spring容器或其他相关资源的引用,并在需要时进行适当的处理。
24 2
|
2月前
|
自然语言处理 Java 开发者
简单了解下Spring中的各种Aware接口实现依赖注入
【8月更文挑战第21天】在Spring框架中,Aware接口系列是一种特殊的机制,它允许Bean在初始化过程中获取到Spring容器或容器中的特定资源,从而实现了更加灵活和强大的依赖注入方式。本文将围绕Spring中的各种Aware接口,详细探讨它们如何帮助开发者在工作和学习中更好地实现依赖注入。
56 0
|
3月前
|
缓存 Java Spring
Spring循环依赖问题之Spring不支持构造器内的强依赖注入如何解决
Spring循环依赖问题之Spring不支持构造器内的强依赖注入如何解决
|
4月前
|
存储 安全 Java
Spring Security 6.x OAuth2登录认证源码分析
上一篇介绍了Spring Security框架中身份认证的架构设计,本篇就OAuth2客户端登录认证的实现源码做一些分析。
172 2
Spring Security 6.x OAuth2登录认证源码分析
|
4月前
|
设计模式 Java 测试技术
Spring Boot中的依赖注入详解
Spring Boot中的依赖注入详解
|
4月前
|
缓存 Java 测试技术
Spring 框架,不只是依赖注入和面向切面那么简单!
【6月更文挑战第25天】Spring框架超越DI和AOP,涵盖事务管理、数据访问抽象如`JdbcTemplate`、消息驱动支持如`@JmsListener`、缓存管理和测试工具。示例代码展示了其简化复杂性的能力,如自动事务处理、数据库操作及消息队列监听。Spring是构建高效企业级应用的全面解决方案。
32 4
下一篇
无影云桌面