【spring】依赖注入之@Autowired寻找能注入的Bean:findAutowireCandidates

@Autowired能注入的Bean

  • 本文源码基于spring-framework-5.3.10。
  • 源码位置:org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(String, Class<?>, DependencyDescriptor)
  • 本文重点讲解@Autowired在依赖注入的时候,他能选择那些Bean进行依赖注入。
  • 这个方法是依赖注入的核心!
  • 先ByType后ByName,所以现在市面上认为@Autowired是ByType方式进行注入的!

findAutowireCandidates源码流程

  • 找出BeanFactory中类型为type的所有的Bean的名字,注意是名字,而不是Bean对象,因为我们可以根据BeanDefinition就能判断和当前type是不是匹配,不用生成Bean对象
  • 把resolvableDependencies中key为type的对象找出来并添加到result中
  • 遍历根据type找出的beanName,判断当前beanName对应的Bean是不是能够被自动注入
  • 先判断beanName对应的BeanDefinition中的autowireCandidate属性,如果为false,表示不能用来进行自动注入,如果为true则继续进行判断
  • 判断当前type是不是泛型,如果是泛型是会把容器中所有的beanName找出来的,如果是这种情况,那么在这一步中就要获取到泛型的真正类型,然后进行匹配,如果当前beanName和当前泛型对应的真实类型匹配,那么则继续判断
  • 如果当前DependencyDescriptor上存在@Qualifier注解,那么则要判断当前beanName上是否定义了Qualifier,并且是否和当前DependencyDescriptor上的Qualifier相等,相等则匹配
  • 经过上述验证之后,当前beanName才能成为一个可注入的,添加到result中

findAutowireCandidates源码分析

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

	// 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);

	// 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置。
	for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
		// 得到当前Bean的类型
		Class<?> autowiringType = classObjectEntry.getKey();
		if (autowiringType.isAssignableFrom(requiredType)) {
			// 获取缓存中的值
			Object autowiringValue = classObjectEntry.getValue();
			// 这里会生成一个Bean的名字,放到缓存中的是没有Bean的名字的
			autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);

			// 类型匹配,将当前值添加进去
			if (requiredType.isInstance(autowiringValue)) {
				result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
				break;
			}
		}
	}

	// 这里理解就是注入同一个Bean的时候,先考虑同类型的其他Bean
	for (String candidate : candidateNames) {
		// 如果不是自己,则判断该candidate到底能不能用来进行自动注入(@Bean(autowireCandidate = true))默认为true
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
			// 不是自己,并且可以注入的时候,调用这个代码:添加候选者
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}

	// 为空要么是真的没有匹配的,要么是匹配的自己
	if (result.isEmpty()) {
		// 需要匹配的类型是不是Map、数组之类的
		boolean multiple = indicatesMultipleBeans(requiredType);
		// Consider fallback matches if the first pass failed to find anything...
		// 如果第一遍找不到任何东西,请考虑回退匹配。
		DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
		// 遍历每个候选者
		for (String candidate : candidateNames) {
			// 不是自己并且可以被注入并且(不是Map、数组之类的或者@Qualifier指定了BeanName的)
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
					(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
				// 添加真正的候选者
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}

		// 匹配的是自己,把自己添加到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;
}

/**
 * 添加候选者
 */
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
		DependencyDescriptor descriptor, Class<?> requiredType) {

	// MultiElementDescriptor的逻辑
	if (descriptor instanceof MultiElementDescriptor) {
		Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
		if (!(beanInstance instanceof NullBean)) {
			candidates.put(candidateName, beanInstance);
		}
	}
	// 单例的逻辑
	else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
			((StreamDependencyDescriptor) descriptor).isOrdered())) {
		// 如果在单例池中存在,则直接放入bean对象
		Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
		candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
	}
	else {
		// 将匹配的beanName,以及beanClass存入
		candidates.put(candidateName, getType(candidateName));
	}
}

获取一个类型对应的所有BeanName

public static String[] beanNamesForTypeIncludingAncestors(
		ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {

	Assert.notNull(lbf, "ListableBeanFactory must not be null");
	// 从本容器中找
	String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
	// 从父容器找并放入result
	if (lbf instanceof HierarchicalBeanFactory) {
		HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
		if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
			// 递归调用
			String[] parentResult = beanNamesForTypeIncludingAncestors(
					(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
			// 把从子父Bean工厂找到的值合并去重(有重复用子类的)
			result = mergeNamesWithParent(result, parentResult, hbf);
		}
	}
	// 返回找到的所有BeanName
	return result;
}

/**
 * 真正的根据类型获取BeanName的外部方法
 */
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {

	// 如果没有冻结,就根据类型去BeanFactory找,如果冻结了,可能就跳过这个if然后去缓存中去拿了
	if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
		return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
	}

	// 把当前类型所匹配的beanName缓存起来
	Map<Class<?>, String[]> cache =
			(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
	// 得到缓冲中的BeanName值
	String[] resolvedBeanNames = cache.get(type);
	// 得到的值不为null,直接返回
	if (resolvedBeanNames != null) {
		return resolvedBeanNames;
	}
	// 值为null,重新去获取值
	resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
	// 进行缓存
	if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
		cache.put(type, resolvedBeanNames);
	}
	// 返回所有的BeanName
	return resolvedBeanNames;
}

/**
 * 真正的根据类型获取BeanName的内部方法
 */
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
	List<String> result = new ArrayList<>();

	// Check all bean definitions.
	// 遍历所有的BeanDefinitions
	for (String beanName : this.beanDefinitionNames) {
		// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
		// 跳过别名
		if (!isAlias(beanName)) {
			try {
				// 得到当前Bean合并后的BeanDefinition
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// Only check bean definition if it is complete.
				// 判断mbd允不允许获取对应类型
				// 首先mdb不能是抽象的,然后allowEagerInit为true,则直接去推测mdb的类型,并进行匹配
				// 如果allowEagerInit为false,那就继续判断,如果mdb还没有加载类并且是懒加载的并且不允许提前加载类,那mbd不能用来进行匹配(因为不允许提前加载类,只能在此mdb自己去创建bean对象时才能去创建类)
				// 如果allowEagerInit为false,并且mbd已经加载类了,或者是非懒加载的,或者允许提前加载类,并且不用必须提前初始化才能获取类型,那么就可以去进行匹配了
				// 这个条件有点复杂,但是如果只考虑大部分流程,则可以忽略这个判断,因为allowEagerInit传进来的基本上都是true
				if (!mbd.isAbstract() && (allowEagerInit ||
						(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
								!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
					// 得到是否是FactoryBean
					boolean isFactoryBean = isFactoryBean(beanName, mbd);
					// 得到BeanDefinitionHolder
					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
					// 匹配标志false
					boolean matchFound = false;
					// 容许FactoryBean初始化
					boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
					// 是否非懒加载
					boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());

					// 当前BeanDefinition不是FactoryBean,就是普通Bean
					if (!isFactoryBean) {
						// 在筛选Bean时,如果仅仅只包括单例,但是beanName对应的又不是单例,则忽略
						if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
							// 判断类型是否匹配
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					}
					else {
						if (includeNonSingletons || isNonLazyDecorated ||
								(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
							// 类型匹配-懒加载
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
						if (!matchFound) {
							// In case of FactoryBean, try to match FactoryBean instance itself next.
							beanName = FACTORY_BEAN_PREFIX + beanName;
							// 类型匹配-FactoryBean
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					}
					if (matchFound) {
						// 将匹配到的,添加到结果集
						result.add(beanName);
					}
				}
			}
			catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
				if (allowEagerInit) {
					throw ex;
				}
				// Probably a placeholder: let's ignore it for type matching purposes.
				LogMessage message = (ex instanceof CannotLoadBeanClassException ?
						LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
						LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
				logger.trace(message, ex);
				// Register exception, in case the bean was accidentally unresolvable.
				onSuppressedException(ex);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Bean definition got removed while we were iterating -> ignore.
			}
		}
	}

	// Check manually registered singletons too.
	// 这里的逻辑是在手动注册的bean中看是否有满足条件的
	for (String beanName : this.manualSingletonNames) {
		try {
			// In case of FactoryBean, match object created by FactoryBean.
			if (isFactoryBean(beanName)) {
				if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
					result.add(beanName);
					// Match found for this bean: do not match FactoryBean itself anymore.
					continue;
				}
				// In case of FactoryBean, try to match FactoryBean itself next.
				beanName = FACTORY_BEAN_PREFIX + beanName;
			}
			// Match raw bean instance (might be raw FactoryBean).
			if (isTypeMatch(beanName, type)) {
				result.add(beanName);
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Shouldn't happen - probably a result of circular reference resolution...
			logger.trace(LogMessage.format(
					"Failed to check manually registered singleton with name '%s'", beanName), ex);
		}
	}

	// 返回结果数组
	return StringUtils.toStringArray(result);
}

判断类型是否匹配

protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)
		throws NoSuchBeanDefinitionException {
	// 判断name所对应的Bean的类型是不是typeToMatch
	// allowFactoryBeanInit表示允不允许在这里实例化FactoryBean对象

	// 如果name是&xxx,那么beanName就是xxx
	String beanName = transformedBeanName(name);
	// name是不是&xxx(FactoryBean)
	boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);

	// Check manually registered singletons.
	// 获取danliBean
	Object beanInstance = getSingleton(beanName, false);
	// 获取到了单例Bean,并且不是空的Bean
	if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
		// FactoryBean的特殊逻辑
		if (beanInstance instanceof FactoryBean) {
			// FactoryBean的外部的类
			if (!isFactoryDereference) {
				// 调用factoryBean.getObjectType()
				Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
				// 返回当前类型不为空并且类型是否匹配
				return (type != null && typeToMatch.isAssignableFrom(type));
			}
			else {
				// 返回类型是否匹配
				return typeToMatch.isInstance(beanInstance);
			}
		}
		// 不是FactoryBean,就是普通Bean
		else if (!isFactoryDereference) {
			// 直接匹配到,返回true。其实常用的方法,看到这一行就可以了
			if (typeToMatch.isInstance(beanInstance)) {
				// Direct match for exposed instance?
				return true;
			}
			// 泛型相关的处理
			else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
				// Generics potentially only match on the target class, not on the proxy...
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				Class<?> targetType = mbd.getTargetType();
				if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
					// Check raw class match as well, making sure it's exposed on the proxy.
					Class<?> classToMatch = typeToMatch.resolve();
					if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
						return false;
					}
					if (typeToMatch.isAssignableFrom(targetType)) {
						return true;
					}
				}
				ResolvableType resolvableType = mbd.targetType;
				if (resolvableType == null) {
					resolvableType = mbd.factoryMethodReturnType;
				}
				return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
			}
		}
		return false;
	}
	// 单例池有,但是没有BeanDefinitionMap中没有,返回false。注册了个空实例
	else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
		// null instance registered
		return false;
	}

	// No singleton instance found -> check bean definition.
	BeanFactory parentBeanFactory = getParentBeanFactory();
	// 存在父工厂,调用父工厂的isTypeMatch方法
	if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
		// No bean definition found in this factory -> delegate to parent.
		return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch);
	}

	// 单例池中没有name对应的Bean对象,就只能根据BeanDefinition来判断出类型了

	// Retrieve corresponding bean definition.
	RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
	BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();

	// Setup the types that we want to match against
	Class<?> classToMatch = typeToMatch.resolve();
	if (classToMatch == null) {
		classToMatch = FactoryBean.class;
	}
	// 为了判断当前beanName,是不是classToMatch或FactoryBean
	Class<?>[] typesToMatch = (FactoryBean.class == classToMatch ?
			new Class<?>[] {classToMatch} : new Class<?>[] {FactoryBean.class, classToMatch});


	// Attempt to predict the bean type
	Class<?> predictedType = null;

	// We're looking for a regular reference but we're a factory bean that has
	// a decorated bean definition. The target bean should be the same type
	// as FactoryBean would ultimately return. 啃
	if (!isFactoryDereference && dbd != null && isFactoryBean(beanName, mbd)) {
		// We should only attempt if the user explicitly set lazy-init to true
		// and we know the merged bean definition is for a factory bean.
		if (!mbd.isLazyInit() || allowFactoryBeanInit) {
			RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
			// getObjectType所方法的类型
			Class<?> targetType = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
			if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) {
				predictedType = targetType;
			}
		}
	}

	// If we couldn't use the target type, try regular prediction.
	if (predictedType == null) {
		predictedType = predictBeanType(beanName, mbd, typesToMatch);
		if (predictedType == null) {
			return false;
		}
	}

	// Attempt to get the actual ResolvableType for the bean.
	ResolvableType beanType = null;

	// If it's a FactoryBean, we want to look at what it creates, not the factory class.
	// BeanDefinition的类型是不是FactoryBean,如果是得先实例化FactoryBean这个对象,然后调用getObjectType方法才能知道具体的类型,前提是allowFactoryBeanInit为true
	if (FactoryBean.class.isAssignableFrom(predictedType)) {
		if (beanInstance == null && !isFactoryDereference) {
			beanType = getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit);
			predictedType = beanType.resolve();
			if (predictedType == null) {
				return false;
			}
		}
	}
	else if (isFactoryDereference) {
		// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
		// type but we nevertheless are being asked to dereference a FactoryBean...
		// Let's check the original bean class and proceed with it if it is a FactoryBean.
		predictedType = predictBeanType(beanName, mbd, FactoryBean.class);
		if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) {
			return false;
		}
	}

	// We don't have an exact type but if bean definition target type or the factory
	// method return type matches the predicted type then we can use that.
	if (beanType == null) {
		ResolvableType definedType = mbd.targetType;
		if (definedType == null) {
			definedType = mbd.factoryMethodReturnType;
		}
		if (definedType != null && definedType.resolve() == predictedType) {
			beanType = definedType;
		}
	}

	// If we have a bean type use it so that generics are considered
	if (beanType != null) {
		return typeToMatch.isAssignableFrom(beanType);
	}

	// If we don't have a bean type, fallback to the predicted type
	return typeToMatch.isAssignableFrom(predictedType);
}

结束语

  • 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
  • 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
  • 关注公众号,后续持续高效的学习JVM!
  • 这个公众号,无广告!!!每日更新!!!
    作者公众号.jpg
posted @ 2022-02-22 23:48  程序java圈  阅读(206)  评论(0编辑  收藏  举报