我是靠谱客的博主 粗心飞鸟,最近开发中收集的这篇文章主要介绍spring依赖查找过程Spring依赖查找resolveDependency()方法总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Spring依赖查找

上篇文章依赖处理过程我们通过简单分析了解到了spring处理依赖时的过程,而其中里面有一个方法 resolveDependency() 就是依赖查找过程。而今天我们主要深入去探讨一下这个方法以及相关的实现

resolveDependency()方法

我们发现,resolveDependency() 方法实现在DefaultListableBeanFactory 这个类里,也就是我们底层IOC容器BeanFactory的实现类

@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
	// 按照惯例不是本文相关代码我们先不关注
	// 这里是获得需要延迟加载(懒加载)的代理对象
	Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
			descriptor, requestingBeanName);
	// 如果获取结果为空,则说明不是懒加载,进入 doResolveDependency() 方法
	if (result == null) {
		result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
	}
	// 若不为空,则说明该依赖是需要延迟处理的依赖,此时直接返回他的代理对象
	return result;
}

resolveDependency 里,首先先判断该bean是否需要延迟处理,如果是的话,就直接返回该bean的代理对象,否则则进入doResolveDependency() 方法

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
	@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

	/*
	 * 如果该bean是集合类型的bean,这里会进行查找,找到后就直接返回,返回null说明
	 * 该bean不是集合类型的bean,进入下面的逻辑
	 */ 
	Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
	if (multipleBeans != null) {
		return multipleBeans;
	}

	// 当走到这里的时候,说明该bean不是集合类型的bean,因此再次进行依赖查找
	Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
	// 如果该map为空则说明没找到相关bean,返回null
	if (matchingBeans.isEmpty()) {
		return null;
	}

	String autowiredBeanName;
	Object instanceCandidate;

	// 如果 map 的 size() 大于 1, 则说明找到两个个以上的bean 
	if (matchingBeans.size() > 1) {
		autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
		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();
	}

	// 将该beanName加入数组	
	autowiredBeanNames.add(autowiredBeanName);
	
	// 获得bean对象,底层是通过beanFactory.getBean()来获取(如果是Class类型的前提下)
	if (instanceCandidate instanceof Class) {
		instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
	}
	Object result = instanceCandidate;
	// 返回获取得到的bean
	return result;
}

接下来我们慢慢分析这段代码
首先进入resolveMultipleBeans() 方法该方法主要是获取集合类型的bean,若该bean不是集合类型,则返回null

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

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

	// 如果是stream流
	if (descriptor instanceof StreamDependencyDescriptor) {...}
	// 如果是数组
	else if (type.isArray()) {...}
	// 如果是其他集合
	else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {...}
	// 如果是map
	else if (Map.class == type) {...}
	else {return null;}
}

以上是对该方法的一些简单分析,其中在每个判断都会调用findAutowireCandidates() 方法。该方法我们将会在下文继续分析

resolveMultipleBeans() 方法后,若该bean不是集合类型bean,则进入下面的逻辑,也就是下面的
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
而这个方法正是我们刚刚所提到的方法

protected Map<String, Object> findAutowireCandidates(
		@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

	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;
			}
		}
	}
	for (String candidate : candidateNames) {
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}
	return result;
}

这段代码的大意是,先查找出所有满足的beanName,然后循环这个Names数组,将其一一加入到result返回

得到result后,继续对matchingBeans做判断
如果该map大于1,则说明存在两个以上满足条件的bean,因此进入determineAutowireCandidate() 方法

@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
	String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
	if (primaryCandidate != null) {
		return primaryCandidate;
	}
	return null;
}

这里简单来看的话,就是去查找beanprimarybeanName,然后将其返回,其底层实际上是去BeanDefinition里找primary属性

获取到该Bean的名称后,然后再通过beanFactory.getBean() 来获取bean

instanceCandidate = matchingBeans.get(autowiredBeanName);
// 如果instanceCandidate为Class类型才会执行这个,这里也失去通过beanFactory.getBean()来获取bean
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);

最终就得到这个bean实体了

总结

依赖处理可以分为以下几个步骤:

  • 第一步:判断是否是延迟加载,是则返回代理对象
  • 第二步:判断是否是集合类型bean,是则返回该集合类型的bean
  • 第三步:将找到所有符合条件的bean加入到map
  • 第四步:对该map做判断:如果map的大小大于1,则去找有primary属性的bean;
  • 第五步:获取到bean,然后返回

最后

以上就是粗心飞鸟为你收集整理的spring依赖查找过程Spring依赖查找resolveDependency()方法总结的全部内容,希望文章能够帮你解决spring依赖查找过程Spring依赖查找resolveDependency()方法总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(31)

评论列表共有 0 条评论

立即
投稿
返回
顶部