结论
- 标记有 @Qualifier 的 autowired 属性会在 DefaultListableBeanFactory#doResolveDependency -> resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter) -> … -> QualifierAnnotationAutowireCandidateResolver#checkQualifiers 过滤掉与 Qualifier.value() 不匹配的 bean
// @see org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates
for (String candidate : candidateNames) {
// isAutowireCandidate(candidate, descriptor) 内部实现可以根据 descriptor#getAnnotations 列表判断
// 需不需要排除不满足 Qualifier 的 bean
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver
// @see org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#checkQualifiers
- 优先匹配标记有
@Primary
的 Bean - 优先匹配标记有
@javax.annotation.Priority
的 Bean - 优先匹配与 autowired 字段或方法参数名称相同的 Bean
// @see org.springframework.beans.factory.config.DependencyDescriptor#getDependencyName
/**
* Determine the name of the wrapped parameter/field.
* @return the declared name (never {@code null})
*/
@Nullable
public String getDependencyName() {
return (this.field != null ? this.field.getName() : obtainMethodParameter().getParameterName());
}
- 如果1、2、3无法确定确定唯一的匹配的 Bean 名称,返回 null
- 4 返回 null 时,autowired 对象属性 required = true 且 autowired 属性不是一个多值类型(如 Collection、数组、Map)、抛出 NoUniqueBeanDefinitionException 异常
// @see org.springframework.beans.factory.config.DependencyDescriptor#resolveNotUnique
@Nullable
public Object resolveNotUnique(ResolvableType type, Map<String, Object> matchingBeans) throws BeansException {
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
}
解析源码参见
org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 匹配 Bean 数量大于一个
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}