@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.最后再看那个与当前变量名称一致的