@Autowired与@Value注解工作原理

一. 找到所有被@Autowired、@Value、@Inject(若项目中有引入)注解的字段和方法

InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  1. 判断是否能从缓存中获取到,获取到并且类型匹配则直接返回

  2. 根据当前bean的class类型,获取所有的注入点

    1. 判断是否有@Autowired、@Value、@Inject注解
    2. 字段处理,获取required值(是否必须注入),static的属性不注入
    3. 方法处理,判断是否有@Required注解,static的方法不注入
    4. 可以成为注入点的字段或方法,封装为AutowiredFieldElement对象,放到List集合

    对象里面封装了传入的对象(Field或者Method)和required属性(是否必须注入)

    1. 循环体最后获取当前目标class对象的父class,循环处理,直至Object.class停止
    2. 将所有筛选过后的注入点的集合,封装到InjectionMetadata对象中
    3. 返回

二. 根据返回的注入点,进行循环处理、注入

metadata.inject(bean, beanName, pvs); 

element.inject(target, beanName, pvs);
  1. 判断是否能从缓存中获取到,获取到则通过反射set,返回
  2. 将字段描述以及required值 封装到DependencyDescriptor对象中
  3. 寻找是否有合适的bean

核心代码:

Object value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
  • 3.1 如果是Optional类型,封装起来,调用doResolveDependency进行解析(同下3.3)
    在这里插入图片描述

  • 3.2 如果是ObjectFactory类型,通过每次调用getObject方法,来装配字段属性,方法内也是调用了doResolveDependency进行解析(同下第3点)

  • 3.3 解析字段类型 (★★★★实际工作原理/步骤★★★★,核心1—6点)

    1. 是否加了@Value注解
      ① 填充并解析“$”占位符
      ② 解析Spring EL表达式 #
      ③ 判断是否有合适的类型转换器
      ④ 返回
      在这里插入图片描述

    2. 根据Type去获取,如果找到一个,判断如果是class,getBean,返回(获取多个,首先把自己排除掉,如果找不到,再把自己作为候选者装配进去,往下走)
      在这里插入图片描述

    3. 拿到存有多个候选者的Map
      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);

    4. 判断是否有@Primary注解(取到唯一,返回)
      5.

    5. 判断是否有@Priority注解(取到唯一,返回)
      在这里插入图片描述

    6. 根据字段名或者方法名字匹配(取到唯一,返回)
      在这里插入图片描述

    7. 如果还是不能确定唯一,required==true或字段不是集合、数组、Map类型 , 报错
      在这里插入图片描述

    8. 拿到唯一的候选者,判断如果是class,getBean,返回
      在这里插入图片描述

    PS:
    1.为什么拿到的候选者有可能是class?
    答:因为取到的时候,这个参数bean可能还没有被实例化
    2.Optional和ObjectFactory
    答:Optional通过get()方法获取对象,如果被注入类型为原型,也只会返回同一个对象
    ObjectFactory通过getObject()方法获取对象,如果被注入类型为原型,每次都会返回一个新对象,且每次是在getObject时才生成

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值