@Autowired注解详细分析

@Autowired注解详细分析

  • @Autowired是由AutowiredAnnotationBeanPostProcessor后置处理器处理的。

  • @Autowired依赖注入是从下面开始的。(这里不讲解为啥从这里开始,如果这步有疑问,欢迎大家留言,可以专门出个博客讲解一下)
    AutowiredAnnotationBeanPostProcessor->postProcessPropertyValues()

  • 要想注入值,先要找到值。
    postProcessPropertyValues()->inject()->AutowiredFieldElement#inject()->resolveDependency()
    经过一系列方法跳转,resolveDependency()就是帮我找值的逻辑。最后走到doResolveDependency()里面包括一下逻辑。

           //根据类型去匹配我们需要赋的值
   		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
   		if (matchingBeans.isEmpty()) {
   			//如果没有匹配到,再看@Autowired注解required属性
   			//是否和AutowiredAnnotationBeanPostProcessor.requiredParameterValue(默认true)相等
   			if (isRequired(descriptor)) {
   			    //会抛出异常
   				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
   			}
   			return null;
   		}

   		String autowiredBeanName;
   		Object instanceCandidate;

   		//如果根据类型匹配到多个
   		if (matchingBeans.size() > 1) {
   			//如果匹配到了多个候选着,1.先看那个是主键.2.再看那个优先级高.3.最后再看与当前变量名称一致的
   			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
   			if (autowiredBeanName == null) {
   				//如果根据类型匹配到了多个但是没有我们想要的那个。
   				//再看@Autowired注解required属性
   				//是否和AutowiredAnnotationBeanPostProcessor.requiredParameterValue(默认true)相等
   				//或者再看type是否属于数组或者是集合接口
   				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
   					//抛出异常
   					return descriptor.resolveNotUnique(type, matchingBeans);
   				}
   				else {
   				    //如果为false,返回null
   					return null;
   				}
   			}
   			instanceCandidate = matchingBeans.get(autowiredBeanName);
   		}
   		else {
   			// 匹配到一个
   			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
   			autowiredBeanName = entry.getKey();
   			instanceCandidate = entry.getValue();
   		}

   		if (autowiredBeanNames != null) {
   			autowiredBeanNames.add(autowiredBeanName);
   		}
   		//这里开始去缓存中获取对象
   		return (instanceCandidate instanceof Class ?
   				descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);

注意:isRequired(descriptor)指的是@Autowired注解required属性是否和AutowiredAnnotationBeanPostProcessor.requiredParameterValue(默认是true,但是是可变的)相等,这句话并不是指的是@Autowired注解required属性值。所以@Autowired(required=true)变量如果在容器中没有找到匹配的会报错,这句话是有问题的。

总结:@Autowired在容器中是按类型寻找的,如果寻找到多个,按顺序看那个是我们需要的1.先看那个是主键.2.再看那个优先级高.3.最后再看那个与当前变量名称一致的

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值