• 7、Spring之依赖注入源码解析(下)


    resolveDependency()实现

    该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。

    1. @Nullable
    2. Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
    3. @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;

    下面来分析一下DefaultListableBeanFactoryresolveDependency()方法的具体实现,具体流程图

    findAutowireCandidates()实现

    根据类型找beanName的底层流程

    对应执行流程图为

    1. 找出BeanFactory中类型为type的所有的Bean的名字,注意是名字,而不是Bean对象,因为我们可以根据BeanDefinition就能判断和当前type是不是匹配,不用生成Bean对象
    2. 把resolvableDependencies中key为type的对象找出来并添加到result中
    3. 遍历根据type找出的beanName,判断当前beanName对应的Bean是不是能够被自动注入
    4. 先判断beanName对应的BeanDefinition中的autowireCandidate属性,如果为false,表示不能用来进行自动注入,如果为true则继续进行判断
    5. 判断当前type是不是泛型,如果是泛型是会把容器中所有的beanName找出来的,如果是这种情况,那么在这一步中就要获取到泛型的真正类型,然后进行匹配,如果当前beanName和当前泛型对应的真实类型匹配,那么则继续判断
    6. 如果当前DependencyDescriptor上存在@Qualifier注解,那么则要判断当前beanName上是否定义了Qualifier,并且是否和当前DependencyDescriptor上的Qualifier相等,相等则匹配
    7. 经过上述验证之后,当前beanName才能成为一个可注入的,添加到result中

    关于依赖注入中泛型注入的实现

    首先在Java反射中,有一个Type接口,表示类型,具体分类为:

    1. raw types:也就是普通Class
    1. parameterized types:对应ParameterizedType接口,泛型类型
    2. array types:对应GenericArrayType,泛型数组
    3. type variables:对应TypeVariable接口,表示类型变量,也就是所定义的泛型,比如T、K
    4. primitive types:基本类型,int、boolean

    Spring中,但注入点是一个泛型时,也是会进行处理的,比如:

    1. @Component
    2. public class UserService extends BaseService, StockService> {
    3. public void test() {
    4. System.out.println(o);
    5. }
    6. }
    7. public class BaseService, S> {
    8. @Autowired
    9. protected O o;
    10. @Autowired
    11. protected S s;
    12. }
    1. Spring扫描时发现UserService是一个Bean
    2. 那就取出注入点,也就是BaseService中的两个属性o、s
    3. 接下来需要按注入点类型进行注入,但是o和s都是泛型,所以Spring需要确定o和s的具体类型。
    4. 因为当前正在创建的是UserService的Bean,所以可以通过userService.getClass().getGenericSuperclass().getTypeName()获取到具体的泛型信息,比如com.zhouyu.service.BaseService
  • 相关阅读:
    BertTokenizer 使用方法
    记录第一个启动代码的诞生
    在.NET 6.0上使用Kestrel配置和自定义HTTPS
    华为云云耀云服务器L实例评测|使用Portainer部署showdoc文档工具
    k8s审计
    Vue.js 3 应用开发与核心源码解析 阅读笔记
    Linux进阶-ipc共享内存
    1711: 【穷举】满足条件的整数
    Django搭建一个简易GPT网站
    PhotoshopCS6视频教程学习笔记-基础部分之一
  • 原文地址:https://blog.csdn.net/zwb_dzw/article/details/132790644