初识Spring源码(3) -- doResolveDependency | findAutowireCandidates | @Order、@Priority调用排序 | @Autowired注入

0. 举个栗子:

@Component
public class SetterBean {

    @Autowired
    @Qualifier("beanService")
    private BeanService beanService;
}

@Configuration
public class ConfigurationBean {

    @Bean(autowireCandidate = false)
    public BeanService beanService1() {
        return new BeanServiceImpl();
    }

    @Bean
    public BeanService beanService() {
        BeanServiceImpl beanService = new BeanServiceImpl();
        beanService.setName("zhangsan");
        return beanService;
    }
}

3. doResolveDependency:

上一篇文章介绍了populateBean属性填充方法,其中通过resolveDependency方法来解析出依赖的属性bean对象,再进行反射
·
 而resolveDependency通常又调用doResolveDependency来解析出依赖的属性bean对象
·
 针对上述栗子,下文省略一些不必要的内容(注入集合、@Value的场景),后面再介绍.

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
	//设置当前的descriptor(存储了方法参数等信息)为当前注入点
	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}

		//从descriptor中获取属性类型
		Class<?> type = descriptor.getDependencyType();
		
		... ... .... // 省略一些不必要的内容(注入集合、@Value的场景)代码
		
		// 查找符合注入属性类型的bean,下文3.1有介绍
		// 这里过滤了 @Bean(autowireCandidate = false)和不符合@Qualifier("beanName")的bean
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			// 为空说明找不到该注入类型的bean,如果注入的属性又是必须的,则抛NoSuchBeanDefinitionException
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		// 查找到多个符合注入属性类型的bean
		if (matchingBeans.size() > 1) {
			// 再过滤找到最优的beanName,进而获取最优的用来创建实例的候选者instanceCandidate
			// 这里挑选@primary、@Priority等优先级高的bean,细节见下文3.3
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
				// 找不到最优的beanName,注入的属性又是必须的,则抛NoUniqueBeanDefinitionException异常
				// 注入的属性非必须,未过滤前就有多个注入属性类型的bean,如果注入的属性不是集合,也抛异常
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
				}
				else {
					return null;
				}
			}
			// 根据beanName获取最优的用来创建属性实例的候选者instanceCandidate
			// key:beanName;value:符合注入属性类型的bean或者bean类型
			instanceCandidate = matchingBeans.get(autowiredBeanName);
		}
		else {
			// We have exactly one match.
			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
			autowiredBeanName = entry.getKey();
			instanceCandidate = entry.getValue();
		}

		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		if (instanceCandidate instanceof Class) {
			// resolveCandidate调用getBean(),根据候选beanName进行属性bean的系列生命周期后返回完整的属性bean对象
			instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
		}
		Object result = instanceCandidate;
		if (result instanceof NullBean) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			result = null;
		}
		if (!ClassUtils.isAssignableValue(type, result)) {
			throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
		}
		return result;
	}
	finally {
		// 和前面那个一样,暂时不知道什么场景有用
		ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
	}
}
 3.1. findAutowireCandidates:

 这里查找符合注入属性类型的bean,会过滤@Bean(autowireCandidate = false)和不符合@Qualifier(“beanName”)的bean
·
 像本栗子的beanService1就会被过滤掉,具体过滤细节见下文3.2

protected Map<String, Object> findAutowireCandidates(
		@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
	// 获取给定类型的所有beanName,包括在祖先工厂中定义的beanName
	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
	// 从已经解析的依赖关系缓存中寻找是否存在我们想要的类型,通常都美誉
	for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
		Class<?> autowiringType = classObjectEntry.getKey();
		if (autowiringType.isAssignableFrom(requiredType)) {
			Object autowiringValue = classObjectEntry.getValue();
			autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
			if (requiredType.isInstance(autowiringValue)) {
				result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
				break;
			}
		}
	}
	// isSelfReference 判断是否是自引用,即注入属性为自身类型
	// isAutowireCandidate 判断是否有资格作为依赖注入的候选者,@Bean(autowireCandidate = false)注解的bean就没有资格
	for (String candidate : candidateNames) {
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
			// 不是自引用又有资格,封装result,见下文3.4.1
			//(key:beanName;value:符合注入属性类型的bean或者bean类型)
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}
	// 没有符合注入属性类型的beanName
	if (result.isEmpty()) {
		// 注入的属性是否是bean的集合类型,本栗子不是
		boolean multiple = indicatesMultipleBeans(requiredType);
		// 使用备用的依赖描述器再去获取一遍符合注入属性类型的beanName
		DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
		for (String candidate : candidateNames) {
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
					(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		// 还是没有符合注入属性类型的beanName,又不是集合类型,考虑自引用,符合条件则将候选者添加到result中

		if (result.isEmpty() && !multiple) {
			// Consider self references as a final pass...
			// but in the case of a dependency collection, not the very same bean itself.
			for (String candidate : candidateNames) {
				if (isSelfReference(beanName, candidate) &&
						(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
						isAutowireCandidate(candidate, fallbackDescriptor)) {
					addCandidateEntry(result, candidate, descriptor, requiredType);
				}
			}
		}
	}
	return result;
}
 3.2. isAutowireCandidate:

 该方法最后会调用AutowireCandidateResolver解析器的resolver.isAutowireCandidate方法来解析候选者bean是否有注入资格

protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
		DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {

	String bdName = BeanFactoryUtils.transformedBeanName(beanName);
	resolveBeanClass(mbd, bdName);
	if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
		new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
	}
	BeanDefinitionHolder holder = (beanName.equals(bdName) ?
			this.mergedBeanDefinitionHolders.computeIfAbsent(beanName,
					key -> new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
			new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
	return resolver.isAutowireCandidate(holder, descriptor);
}

 在了解isAutowireCandidate前,先了解AutowireCandidateResolver接口实现类的AutowireCandidateResolver方法,类图如下:

在这里插入图片描述

  3.2.1. SimpleAutowireCandidateResolver#isAutowireCandidate:

 SimpleAutowireCandidateResolver 是一个简单的解析器,直接取bd.autowireCandidate值,默认为true,也就是可注入
·
 本栗子beanService1使用 @Bean(autowireCandidate = false),即这个bean的autowireCandidate为false,不可注入

public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
	return bdHolder.getBeanDefinition().isAutowireCandidate();
}
  3.2.2. GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate:

 GenericTypeAwareAutowireCandidateResolver 是一个泛型依赖的解析器

  • 先调用父类SimpleAutowireCandidateResolver来判断该候选bean是否可注入,允许则进行泛型匹配
  • 主要在checkGenericTypeMatch方法匹配泛型:
  •  如果待依赖注入的属性类型不包含泛型,直接返回true,即这个候选bean允许取注入,本栗子不涉及泛型,返回true
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
	if (!super.isAutowireCandidate(bdHolder, descriptor)) {
		return false;
	}
	return checkGenericTypeMatch(bdHolder, descriptor);
}
  3.2.3. QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate:

 QualifierAnnotationAutowireCandidateResolver是处理@Qualifier注解的解析器

  • 先调用父类(即上述候选解析器)判断是否允许注入、泛型匹配
  • 都满足则进行待依赖注入属性的@Qualifier匹配,匹配成功返回true,即这个候选bean允许注入
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
	// 父类校验:判断是否允许注入、泛型匹配
	boolean match = super.isAutowireCandidate(bdHolder, descriptor);
	if (match) {
		// checkQualifiers来校验@Qualifier规则,第二个参数传属性注解信息数组
		// bdHolder相当于候选bean,即符合属性类型的bean;descriptor是待依赖注入属性bean的描述器
		match = checkQualifiers(bdHolder, descriptor.getAnnotations());
		// 进一步校验标注在构造函数或方法上的@Qualifier注解规则
		if (match) {
			MethodParameter methodParam = descriptor.getMethodParameter();
			// 如果当前是依赖注入属性,methodParam=null,注解返回match
			if (methodParam != null) {
				Method method = methodParam.getMethod();
				// 校验标注在构造函数或方法上的@Qualifier注解规则
				if (method == null || void.class == method.getReturnType()) {
					match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
				}
			}
		}
	}
	return match;
}
  3.2.4. checkQualifiers:

 循环遍历属性上的注解,看是否是@Qualifier,是的话通常会取匹配注解的属性值是否和属性beanName一致
·
 一致则不需要进行元注解匹配,否则会遍历一层元注解,进行元注解匹配,因为Spring还支持@Qualifier派生注解
·
 关于元注解可以参考:链接的3.3的内容

protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
	if (ObjectUtils.isEmpty(annotationsToSearch)) {
		return true;
	}
	SimpleTypeConverter typeConverter = new SimpleTypeConverter();
	// 遍历属性注解信息数组
	for (Annotation annotation : annotationsToSearch) {
		Class<? extends Annotation> type = annotation.annotationType();
		boolean checkMeta = true;
		boolean fallbackToMeta = false;
		// 判断是不是@Qualifier注解
		if (isQualifier(type)) {
			// 通常会取匹配注解的属性值是否和候选bean的beanName一致
			if (!checkQualifier(bdHolder, annotation, typeConverter)) {
				// 表示第一次匹配失败,进而往下进行元注解匹配
				fallbackToMeta = true;
			}
			else {
				// 匹配成功,就不用往下进行元注解匹配
				checkMeta = false;
			}
		}
		// 本身不是@Qualifier或匹配失败都会进行元注解匹配
		if (checkMeta) {
			boolean foundMeta = false;
			// 遍历元注解,也就是注解里的注解。只遍历一层元注解
			for (Annotation metaAnn : type.getAnnotations()) {
				Class<? extends Annotation> metaType = metaAnn.annotationType();
				// 判断元注解是不是@Qualifier注解
				if (isQualifier(metaType)) {
					foundMeta = true;
					// 元注解匹配
					if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
							!checkQualifier(bdHolder, metaAnn, typeConverter)) {
						return false;
					}
				}
			}
			// 两次都匹配失败,则false
			if (fallbackToMeta && !foundMeta) {
				return false;
			}
		}
	}
	return true;
}
  3.2.5. isAutowireCandidate小结:

 该方法最后会调用resolver.isAutowireCandidate,经过不同的解析器去处理,返回true即这个候选bean可以注入:

  • 简单候选解析器去判断autowireCandidate是否是true
  • 泛型候选解析器去匹配泛型,本栗子不是泛型返回true
  • @Qualifier注解的解析器去匹配@Qualifier规则(通常匹配属性是否是@Qualifier注解和注解属性值),匹配成功返回true
 3.3. determineAutowireCandidate:

 经过findAutowireCandidates匹配(也就是autowireCandidate和@Qualifier匹配)后,还存在多个候选bean
·
 则在此处筛选出最优的候选bean,涉及@Primary、@Priority注解

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
	// 获取待依赖注入属性的类型
	Class<?> requiredType = descriptor.getDependencyType();
	// 先匹配候选bean是有@Primary
	String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
	// 通过@Primary成功,返回候选bean的beanName
	if (primaryCandidate != null) {
		return primaryCandidate;
	}
	
	// @Primary匹配失败,再通过@Priority进行优先级匹配,属性值越小优先级越高
	String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
	// @Priority高优先级匹配成功,返回候选bean的beanName
	if (priorityCandidate != null) {
		return priorityCandidate;
	}
	// @Primary、@Priority都匹配失败,最后匹配候选beanName和属性beanName是否一致,一致则返回候选bean的beanName
	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;
		}
	}
	// 匹配失败,表示没有符合的bean可以注入
	return null;
}
  3.3.0. 栗子:
@Configuration
public class ConfigurationBean {

    @Bean
    // @Primary
    public BeanService beanService1() {
        return new BeanServiceImpl();
    }
        
    @Bean
    public BeanService beanService() {
        BeanServiceImpl beanService = new BeanServiceImpl();
        beanService.setName("zhangsan");
        return beanService;
    }
}

@Component
public class SetterBean {

    @Autowired
    private BeanService beanService;
}

@Component
@Priority(1)
public class BeanServicePriority implements BeanService {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}
  3.3.1. determinePrimaryCandidate:

 循环遍历候选bean上是否有@Primary注解(判断bd.primary,默认false,有注解时为true)

protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
	String primaryBeanName = null;
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateBeanName = entry.getKey();
		Object beanInstance = entry.getValue();
		// 循环遍历候选bean上是否有@Primary注解,只能一个候选bean有注解
		if (isPrimary(candidateBeanName, beanInstance)) {
			// 不等于null,说明已经有过候选bean是@Primary注解的
			if (primaryBeanName != null) {
				boolean candidateLocal = containsBeanDefinition(candidateBeanName);
				boolean primaryLocal = containsBeanDefinition(primaryBeanName);
				// 多个候选bean标注@Primary注解,通常抛异常
				if (candidateLocal && primaryLocal) {
					throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
							"more than one 'primary' bean found among candidates: " + candidates.keySet());
				}
				else if (candidateLocal) {
					primaryBeanName = candidateBeanName;
				}
			}
			else {
				// @Primary匹配成功,作为待返回的候选beanName
				primaryBeanName = candidateBeanName;
			}
		}
	}
	return primaryBeanName;
}
  3.3.2. determineHighestPriorityCandidate:

 循环遍历获取候选bean的@Priority(1)注解的优先级,优先级数值越小,越优先
·
 【注意】:@Priority注解只能标注在方法或者类上,和@Bean一起不生效
·
 也许有人会想起@Order注解,该注解不影响依赖注入,可以参考@Order注解文章介绍

protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
	String highestPriorityBeanName = null;
	Integer highestPriority = null;
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateBeanName = entry.getKey();
		Object beanInstance = entry.getValue();
		if (beanInstance != null) {
			// 循环遍历获取候选bean的@Priority(1)注解的优先级数值
			Integer candidatePriority = getPriority(beanInstance);
			if (candidatePriority != null) {
				if (highestPriorityBeanName != null) {
					// 多个@Priority注解的候选bean,且优先级数值相等,抛异常
					if (candidatePriority.equals(highestPriority)) {
						throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
								"Multiple beans found with the same priority ('" + highestPriority +
								"') among candidates: " + candidates.keySet());
					}
					// 多个@Priority注解的候选bean,且优先级数值小的优先
					else if (candidatePriority < highestPriority) {
						// 高优先级的候选bean作为返回
						highestPriorityBeanName = candidateBeanName;
						highestPriority = candidatePriority;
					}
				}
				else {
					// 优先级匹配成功,作为待返回的候选beanName
					highestPriorityBeanName = candidateBeanName;
					highestPriority = candidatePriority;
				}
			}
		}
	}
	return highestPriorityBeanName;
}
 3.4. resolveMultipleBeans:
  3.4.0. 栗子:
@Configuration
public class ConfigurationBean {

    @Bean
    public BeanService beanService1() {
        return new BeanServiceImpl();
    }

    @Bean
    @Order(1)
    public BeanService beanService() {
        BeanServiceImpl beanService = new BeanServiceImpl();
        beanService.setName("zhangsan");
        return beanService;
    }
}

@Component
public class SetterBean {

    @Autowired
    private List<BeanService> list;
    
    //@Autowired
    //private Map<String,BeanService> map;
    
    //@Autowired
    //private BeanService[] array;
}

@Component
@Order(3)
public class BeanServicePriority implements BeanService {
    private String name;
}

 此方法是注入依赖bean的集合对象

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
		... ... ...
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}
		... ... ...
}		

 通过核心方法findAutowireCandidates将依赖的bean获取符合注入的实例,封装到matchingBeans
·
 通过类型转换器,将matchingBeans符合依赖注入的bean转换成对对应集合类型(Array、Collection、Map)
·
 对转换后的集合进行排序(Map除外),与@Order、@Priority(x)注解有关,优先级值越小越先调用,可参考链接

private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {

	Class<?> type = descriptor.getDependencyType();

	... ... ...
	else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
		Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
		if (elementType == null) {
			return null;
		}
		// 会获取符合注入的bean实例,封装到matchingBeans
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
				new MultiElementDescriptor(descriptor));
		if (matchingBeans.isEmpty()) {
			return null;
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
		// 将matchingBeans的bean实例转化成List
		Object result = converter.convertIfNecessary(matchingBeans.values(), type);
		if (result instanceof List) {
			if (((List<?>) result).size() > 1) {
				Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
				// 存在多个bean时,调用排序,@Order注解有关,属性值越小越先调用执行
				if (comparator != null) {
					((List<?>) result).sort(comparator);
				}
			}
		}
		return result;
	}
	else if (Map.class == type) {
	... ... ...
}
  3.4.1. addCandidateEntry:

 在findAutowireCandidates中,符合注入的候选bean会被通过getBean获取实例,封装返回

private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
		DependencyDescriptor descriptor, Class<?> requiredType) {
	// 注入的属性是集合类型
	if (descriptor instanceof MultiElementDescriptor) {
		// 通过beanFactory.getBean(beanName)获取注入的实例
		Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
		if (!(beanInstance instanceof NullBean)) {
			// 封装到candidates,封装的是候选bean实例
			candidates.put(candidateName, beanInstance);
		}
	}
	else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
			((StreamDependencyDescriptor) descriptor).isOrdered())) {
		Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
		candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
	}
	else {
		// 注入的属性的单个bean,封装的是候选bean类型
		candidates.put(candidateName, getType(candidateName));
	}
}
  3.4.2. 关于@Primary、@Order、@Priority(x)调用排序:

 @Primary不参与调用排序,@Order、@Priority(x)优先级值越小,越优先调用;
·
 优先级(值)相同,按默认的bean注册顺序来调用
`
 没有优先级注解或者@Order不填优先级值,默认值为Integer.MAX_VALUE,即按默认的bean注册顺序来调用
·
【原理】:主要是matchingBeans是从注册的bean中获取的,即beanDefinitionNames;再针对matchingBeans作优先级排序

 3.5. 小结:

 如果待注入的属性是bean的集合类型(Array、Collection、Map):

  • 根据属性类型获取候选bean,过滤autowireCandidate=false;@Qualifier不匹配的候选bean
  • 根据候选bean的beanName,调用beanFactory.getBean(beanName)获取候选bean实例
  • 封装到候选bean集合matchingBeans(key:beanName; value:候选bean实例)
  • 通过类型转换器,转换成对应集合类型,再对集合(Map除外),进行调用排序(涉及@Order、@Priority(x))

 如果待注入的属性是bean:

  • 根据属性类型获取候选bean,过滤autowireCandidate=false;@Qualifier不匹配的候选bean
  • 封装到候选bean集合matchingBeans(key:beanName; value:候选bean实例或实例类型)
  • 经过过滤还有多个候选bean:
    ·
     选取标注@Primary的候选bean为最优bean
     没有@Primary则选取优先级最高的(Order、@Priority优先级越小优先级越高)作为最优bean
     没有优先级注解@Order、@Priority,最后通过属性beanName去匹配候选Bean的beanName,匹配成功则作为最优bean,否则抛异常
    ·
  • 经过上述过滤,找到最优的候选bean
  • 如果最优的候选bean在matchingBeans的value是bean的类型,则beanFactory.getBean(beanName)获取实例再返回,否则直接返回实例

 到这里,我们也可以知道@Autowired默认是byType注入的
`
  中间还依次经历autowireCandidate、@Qualifier、@Primary、@Priority的过滤
·
 最后才byName注入

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值