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月前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
82 1
|
5天前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
19 6
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
Java 数据库 数据安全/隐私保护
轻松掌握Spring依赖注入:打造你的登录验证系统
本文以轻松活泼的风格,带领读者走进Spring框架中的依赖注入和登录验证的世界。通过详细的步骤和代码示例,我们从DAO层的创建到Service层的实现,再到Spring配置文件的编写,最后通过测试类验证功能,一步步构建了一个简单的登录验证系统。文章不仅提供了实用的技术指导,还以口语化和生动的语言,让学习变得不再枯燥。
49 2
|
7月前
|
XML Java 测试技术
Spring Boot中的依赖注入和控制反转
Spring Boot中的依赖注入和控制反转
|
3月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
47 1
|
4月前
|
缓存 JavaScript Java
Spring之FactoryBean的处理底层源码分析
本文介绍了Spring框架中FactoryBean的重要作用及其使用方法。通过一个简单的示例展示了如何通过FactoryBean返回一个User对象,并解释了在调用`getBean()`方法时,传入名称前添加`&`符号会改变返回对象类型的原因。进一步深入源码分析,详细说明了`getBean()`方法内部对FactoryBean的处理逻辑,解释了为何添加`&`符号会导致不同的行为。最后,通过具体代码片段展示了这一过程的关键步骤。
Spring之FactoryBean的处理底层源码分析
|
3月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
45 1
|
3月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
45 0
|
6月前
|
设计模式 自然语言处理 Java
简单了解下Spring中的各种Aware接口实现依赖注入
在Spring框架中,Aware接口是一组用于提供特定资源或环境信息的回调接口。这些接口被设计用来允许Bean获取对Spring容器或其他相关资源的引用,并在需要时进行适当的处理。
54 2