11、Spring之Bean生命周期~依赖注入(2)

11、Spring之Bean生命周期~依赖注入(2)

依赖注入

这里我们重点解析AutowiredAnnotationBeanPostProcessor的源码,为什么要解析AutowiredAnnotationBeanPostProcessor呢,因为AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()方法中会寻找Bean对象的注入点,AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法中会给注入点赋值;接下来我们挨个分析。

查找注入点

postProcessMergedBeanDefinition()方法详解

java 复制代码
/**
 * BeanDefinition的后置处理
 */
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}

这里可以看到调用findAutowiringMetadata()方法寻找注入点;

对注入点进行赋值

postProcessProperties()方法详解

java 复制代码
/**
 * 给注入点赋值
 */

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	// 找注入点(所有被@Autowired注解了的Field或Method)
	// 因为在postProcessMergedBeanDefinition方法已经找到啦所有的注入点,这一步只是从缓存中获取所有的注入点
	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	} catch (BeanCreationException ex) {
		throw ex;
	} catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
	}
	return pvs;
}

调用findAutowiringMetadata()方法到BeanName对应的所有注入点,调用InjectionMetadata.inject()方法

InjectionMetadata.inject()方法

InjectionMetadata.inject()方法详解

java 复制代码
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Collection<InjectedElement> checkedElements = this.checkedElements;
	Collection<InjectedElement> elementsToIterate =
			(checkedElements != null ? checkedElements : this.injectedElements);
	if (!elementsToIterate.isEmpty()) {
		// 遍历每个注入点进行依赖注入
		for (InjectedElement element : elementsToIterate) {
			element.inject(target, beanName, pvs);
		}
	}
}

通过上述代码可以看到,如果注入点集合不是空,调用InjectedElement.inject()方法,因为InjectedElement是一个抽象类,有两个子类:AutowiredFieldElement和AutowiredMethodElement;

AutowiredFieldElement.inject()方法

AutowiredFieldElement.inject()方法详解

java 复制代码
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

	Field field = (Field) this.member;
	Object value;
	if (this.cached) {
		// 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true
		// 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了
		// 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象
		try {
			value = resolvedCachedArgument(beanName, this.cachedFieldValue);
		} catch (NoSuchBeanDefinitionException ex) {
			// Unexpected removal of target bean for cached argument -> re-resolve
			value = resolveFieldValue(field, bean, beanName);
		}
	} else {
		// 根据filed从BeanFactory中查到的匹配的Bean对象
		value = resolveFieldValue(field, bean, beanName);
	}

	// 反射给filed赋值
	if (value != null) {
		ReflectionUtils.makeAccessible(field);
		field.set(bean, value);
	}
}

通过上述代码我们可以看到这里大概分三步:

  1. 判断是否有缓存;如果有缓存调用resolvedCachedArgument()方法;
  2. 没缓存调用resolveFieldValue()方法
  3. 最后反射赋值;

返回InjectionMetadata.inject()方法

resolveFieldValue()方法

resolveFieldValue()方法详解

java 复制代码
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {

	DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
	desc.setContainingClass(bean.getClass());

	Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
	Assert.state(beanFactory != null, "No BeanFactory available");
	TypeConverter typeConverter = beanFactory.getTypeConverter();
	Object value;
	try {
		value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
	} catch (BeansException ex) {
		throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
	}
	synchronized (this) {
		if (!this.cached) {
			Object cachedFieldValue = null;
			if (value != null || this.required) {
				cachedFieldValue = desc;
				// 注册一下beanName依赖了autowiredBeanNames,
				registerDependentBeans(beanName, autowiredBeanNames);
				if (autowiredBeanNames.size() == 1) {
					String autowiredBeanName = autowiredBeanNames.iterator().next();
					if (beanFactory.containsBean(autowiredBeanName) &&
							beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
						// 构造一个ShortcutDependencyDescriptor作为缓存,保存了当前filed所匹配的autowiredBeanName,而不是对应的bean对象(考虑原型bean)
						cachedFieldValue = new ShortcutDependencyDescriptor(
								desc, autowiredBeanName, field.getType());
					}
				}
			}
			this.cachedFieldValue = cachedFieldValue;
			this.cached = true;
		}
	}
	return value;
}

通过上述代码我们可以看到:

  1. 首先创建DependencyDescriptor对象;
  2. 经过一系列判断之后,调用AutowireCapableBeanFactory的resolveDependency方法,因为DefaultListableBeanFactory实现啦AutowireCapableBeanFactory接口,最终会走到DefaultListableBeanFactory的resolveDependency()方法
  3. 找到要注入的Bean对象之后会调用registerDependentBeans()方法,记录依赖关系;

返回AutowiredFieldElement.inject()方法

resolveDependency方法

resolveDependency()方法详解

java 复制代码
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
								@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) 
		throws BeansException {
	// 用来获取方法入参名字的
	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

	// 所需要的类型是Optional
	if (Optional.class == descriptor.getDependencyType()) {
		return createOptionalDependency(descriptor, requestingBeanName);
	}
	// 所需要的的类型是ObjectFactory,或ObjectProvider
	else if (ObjectFactory.class == descriptor.getDependencyType() ||
			ObjectProvider.class == descriptor.getDependencyType()) {
		return new DependencyObjectProvider(descriptor, requestingBeanName);
	} else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
		return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
	} else {
		// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);

		if (result == null) {
			// descriptor表示某个属性或某个set方法
			// requestingBeanName表示正在进行依赖注入的Bean
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

这里我们看到的是DefaultListableBeanFactory类的resolveDependency()方法:

  1. 如果现在方法参数不是null,初始化ParameterNameDiscoverer对象;
  2. 如果需要的类型是Optional,会调用createOptionalDependency()方法,其实还是调用doResolveDependency()方法,只是将返回值封装成Optional类型;
  3. 如果需要的类型是ObjectFactory或者是ObjectProvider,会创建DependencyObjectProvider对象返回;
  4. 如果需要的类型是javaxInjectProviderClass,会创建Jsr330Provider对象返回;
  5. 再往下我们看到,如果属性或者方法上有@Lazy注解会创建代理对象;
  6. 如果代理对象是null,调用doResolveDependency()方法

返回resolveFieldValue()方法

返回resolveMethodArguments()方法

createOptionalDependency()方法

createOptionalDependency()方法详解

java 复制代码
/**
 * Create an {@link Optional} wrapper for the specified dependency.
 */
private Optional<?> createOptionalDependency(
		DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {

	DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
		@Override
		public boolean isRequired() {
			return false;
		}

		@Override
		public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
			return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
					super.resolveCandidate(beanName, requiredType, beanFactory));
		}
	};
	Object result = doResolveDependency(descriptorToUse, beanName, null, null);
	return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
}

通过上述代码我么可以看到,会调用doResolveDependency()方法,将返回值封装成Optional类型;

返回resolveDependency()方法

doResolveDependency()方法

doResolveDependency()方法详解

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

	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}

		Class<?> type = descriptor.getDependencyType();
		// 获取@Value所指定的值
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
				// 占位符填充(${})
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ?
						getMergedBeanDefinition(beanName) : null);
				// 解析Spring表达式(#{})
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			// 将value转化为descriptor所对应的类型
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			try {
				return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
			} catch (UnsupportedOperationException ex) {
				// A custom TypeConverter which does not support TypeDescriptor resolution...
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
		}

		// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}

		// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			// required为true,抛异常
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		if (matchingBeans.size() > 1) {
			// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
			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);
		} else {
			// We have exactly one match.
			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
			autowiredBeanName = entry.getKey();
			instanceCandidate = entry.getValue();
		}

		// 记录匹配过的beanName
		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
		if (instanceCandidate instanceof Class) {
			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);
	}
}

通过上述代码我们可以看到:

  1. 首先会判断当前属性的依赖关系是否有值,有值说明之前做过依赖注入,直接用之前找到的值,不用再次查找,起到缓存的作用;
  2. 如果有@value注解,对@value注解解析,拿到返回值直接返回;
  3. 调用resolveMultipleBeans()方法,主要逻辑:如果需要注入的类型的是:Stream、Array、Collection或Map,将descriptor类型所匹配的所有bean对象封装成Stream、Array、Collection或Map,进行返回;
  4. 调用findAutowireCandidates()方法查找类型对象的Bean对象或者BeanClass;
  5. 如果查找的对象是0,且required为true,会报错,required不是true,返回null;
  6. 如果查找的对象大于1,有多个,调用determineAutowireCandidate()方法确认具体是哪一个;
  7. 如果查找的对象只有一个;
  8. 记录依赖关系,这个类型和哪些BeanName能匹配上;
  9. 如果查找到的对象还没有进行实例化,进行实例化操作;
  10. 判断找到的对象是否是NullBean,如果是NullBean且required属性是true,会报错;

在这个方法最后有一个finally代码块,这里先标记一下,这里是解决循环依赖的一部分代码;

返回createOptionalDependency()方法

返回resolveDependency()方法

determineAutowireCandidate()方法

determineAutowireCandidate()方法详解

java 复制代码
/**
 * Determine the autowire candidate in the given set of beans.
 * <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
 *
 * @param candidates a Map of candidate names and candidate instances
 *                   that match the required type, as returned by {@link #findAutowireCandidates}
 * @param descriptor the target dependency to match against
 * @return the name of the autowire candidate, or {@code null} if none found
 */
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
	Class<?> requiredType = descriptor.getDependencyType();
	// candidates表示根据类型所找到的多个Bean,判断这些Bean中是否有一个是@Primary的
	String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
	if (primaryCandidate != null) {
		return primaryCandidate;
	}

	// 取优先级最高的Bean
	String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
	if (priorityCandidate != null) {
		return priorityCandidate;
	}

	logger.info("byName赋值逻辑===开始");

	// Fallback
	// 匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateName = entry.getKey();
		Object beanInstance = entry.getValue();


		// resolvableDependencies记录了某个类型对应某个Bean,启动Spring时会进行设置,比如BeanFactory.class对应BeanFactory实例
		// 注意:如果是Spring自己的byType,descriptor.getDependencyName()将返回空,只有是@Autowired才会方法属性名或方法参数名
		if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
				matchesBeanName(candidateName, descriptor.getDependencyName())) {
			logger.info("byName赋值逻辑===结束");
			return candidateName;
		}
	}
	return null;
}

通过上述代码,我们可以看到:

  1. 首先会调用determinePrimaryCandidate()方法,遍历所有符合要求的Bean对象,这些Bean对象有一个有@Primary注解,返回这个有@Primary注解的Bean对象,如果有多个Bean对象都有@Primary注解,会报错;
  2. 然后调用determineHighestPriorityCandidate()方法,遍历Bean上是否有@Priority注解,如果有取优先级最高的Bean对象(数字越小优先级越高),通过如果有多个@Priority注解的值是一样的,会报错;
  3. 最后遍历所有符合要求的Bean对象,根据BeanName匹配;

返回doResolveDependency()方法

resolveMultipleBeans()方法

resolveMultipleBeans()方法详解

java 复制代码
@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
									@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {

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

	if (descriptor instanceof StreamDependencyDescriptor) {
		// 找到type所匹配的所有bean
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}

		// 构造成一个stream
		Stream<Object> stream = matchingBeans.keySet().stream()
				.map(name -> descriptor.resolveCandidate(name, type, this))
				.filter(bean -> !(bean instanceof NullBean));

		// 排序
		if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
			stream = stream.sorted(adaptOrderComparator(matchingBeans));
		}
		return stream;
	} else if (type.isArray()) {
		// 得到数组元素的类型
		Class<?> componentType = type.getComponentType();
		ResolvableType resolvableType = descriptor.getResolvableType();
		Class<?> resolvedArrayType = resolvableType.resolve(type);
		if (resolvedArrayType != type) {
			componentType = resolvableType.getComponentType().resolve();
		}
		if (componentType == null) {
			return null;
		}
		// 根据数组元素类型找到所匹配的所有Bean
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
				new MultiElementDescriptor(descriptor));
		if (matchingBeans.isEmpty()) {
			return null;
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		// 进行类型转化
		TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
		Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
		if (result instanceof Object[]) {
			Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
			if (comparator != null) {
				Arrays.sort((Object[]) result, comparator);
			}
		}
		return result;
	} else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
		Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
		if (elementType == null) {
			return null;
		}
		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());
		Object result = converter.convertIfNecessary(matchingBeans.values(), type);
		if (result instanceof List) {
			if (((List<?>) result).size() > 1) {
				Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
				if (comparator != null) {
					((List<?>) result).sort(comparator);
				}
			}
		}
		return result;
	} else if (Map.class == type) {
		ResolvableType mapType = descriptor.getResolvableType().asMap();
		Class<?> keyType = mapType.resolveGeneric(0);
		// 如果Map的key不是String
		if (String.class != keyType) {
			return null;
		}
		Class<?> valueType = mapType.resolveGeneric(1);
		if (valueType == null) {
			return null;
		}
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
				new MultiElementDescriptor(descriptor));
		if (matchingBeans.isEmpty()) {
			return null;
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		return matchingBeans;
	} else {
		return null;
	}
}

通过上述代码可以看到:

对属性类型依次进行Stream、Array、Collection、Map判断,然后调用findAutowireCandidates()方法查询类型对应的Bean对象信息,拿到所有的Bean对象,将其封装成属性对应的类型;

返回doResolveDependency()方法

findAutowireCandidates()方法

findAutowireCandidates()方法详解

java 复制代码
/**
 * Find bean instances that match the required type.
 * Called during autowiring for the specified bean.
 *
 * @param beanName     the name of the bean that is about to be wired
 * @param requiredType the actual type of bean to look for
 *                     (may be an array component type or collection element type)
 * @param descriptor   the descriptor of the dependency to resolve
 * @return a Map of candidate names and candidate instances that match
 * the required type (never {@code null})
 * @throws BeansException in case of errors
 * @see #autowireByType
 * @see #autowireConstructor
 */
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()) {
		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) {
		// 如果不是自己,则判断该candidate到底能不能用来进行自动注入
		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) {
			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;
}

通过上述代码我们可以看到:

  1. 首先调用BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法查找属性类型对应的BeanName,为什么是BeanName,因为bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化;
  2. 再往下还会去查找resolvableDependencies中key为是这个类型的对象找出来并添加到result中;
  3. 再往下会循环通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法查找到的BeanName;
  4. 首先调用isSelfReference()方法判断当前Bean对象和要注入的Bean是不是一个Bean;
  5. 如果是自己直接跳过,如果不是自己还会调用isAutowireCandidate()方法判断,这个Bean是否可以进行依赖注入,比如@Bean(autowireCandidate = false),表示这个Bean是不能注入给其他Bean的;
  6. 如果两个判断通过调用addCandidateEntry()方法,将Bean对象放入result集合中;
  7. 判断result集合是否为空,不为空直接返回;
  8. 为空,进入下面判断逻辑;
  9. 第一块逻辑其实是校验要注入的对象是不是Arra、Collection或者Map之类的,还是会将自己排除掉,然后判断Bean是否可以进行依赖注入,有@Qualifier注解的话,判断@Qualifier注解是否满足条件;
  10. 如果还是没有满足结果的Bean对象,说明要自己注入自己,再判断Bean是否可以进行依赖注入,满足条件将自己放入result集合中;

返回resolveMultipleBeans()方法

返回doResolveDependency()方法

beanNamesForTypeIncludingAncestors()方法

beanNamesForTypeIncludingAncestors()方法详解

java 复制代码
/**
 * Get all bean names for the given type, including those defined in ancestor
 * factories. Will return unique names in case of overridden bean definitions.
 * <p>Does consider objects created by FactoryBeans if the "allowEagerInit"
 * flag is set, which means that FactoryBeans will get initialized. If the
 * object created by the FactoryBean doesn't match, the raw FactoryBean itself
 * will be matched against the type. If "allowEagerInit" is not set,
 * only raw FactoryBeans will be checked (which doesn't require initialization
 * of each FactoryBean).
 * @param lbf the bean factory
 * @param includeNonSingletons whether to include prototype or scoped beans too
 * or just singletons (also applies to FactoryBeans)
 * @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
 * <i>objects created by FactoryBeans</i> (or by factory methods with a
 * "factory-bean" reference) for the type check. Note that FactoryBeans need to be
 * eagerly initialized to determine their type: So be aware that passing in "true"
 * for this flag will initialize FactoryBeans and "factory-bean" references.
 * @param type the type that beans must match
 * @return the array of matching bean names, or an empty array if none
 * @see ListableBeanFactory#getBeanNamesForType(Class, boolean, boolean)
 */
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);
			result = mergeNamesWithParent(result, parentResult, hbf);
		}
	}
	return result;
}

通过上述代码,我们可以看到,这个方法是一个递归,先从当前BeanFactory中查找,再从父BeanFactory中查找,最后将所有的BeanName放入String数组中,这里没有做去重;

  1. 首先会调用ListableBeanFactory接口的getBeanNamesForType()方法,因为findAutowireCandidates()方法在调用beanNamesForTypeIncludingAncestors()方法时,第一个参数传的是this,所以这里的getBeanNamesForType()方法会走到DefaultListableBeanFactory类的getBeanNamesForType()方法

返回findAutowireCandidates()方法

getBeanNamesForType()方法

getBeanNamesForType()方法详解

java 复制代码
@Override
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);
	String[] resolvedBeanNames = cache.get(type);
	if (resolvedBeanNames != null) {
		return resolvedBeanNames;
	}
	resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
	if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
		cache.put(type, resolvedBeanNames);
	}
	return resolvedBeanNames;
}

通过上述段我们可以看到,这里核心是调用doGetBeanNamesForType()方法

返回BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法

doGetBeanNamesForType()方法

doGetBeanNamesForType()方法详解

java 复制代码
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
	List<String> result = new ArrayList<>();

	// Check all bean definitions.
	// 遍历所有的BeanName
	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 {
				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()))) {

					boolean isFactoryBean = isFactoryBean(beanName, mbd);
					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
					boolean matchFound = false;
					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;
							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.
	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);
}

通过上述代码我们可以看到:

  1. 循环所有的BeanName;
  2. 判断当前BeanName不是别名;
  3. 通过BeanName拿到合并后的BeanDefinition(可以直接创建Bean对象的BeanDefinition);
  4. 首先BeanDefinition不能是抽象的;
  5. 如果allowEagerInit为true,则直接去推测BeanDefinition的类型,并进行匹配;
  6. 如果allowEagerInit为false,那就继续判断,如果BeanDefinition还没有加载类并且是懒加载的并且不允许提前加载类,那BeanDefinition不能用来进行匹配(因为不允许提前加载类,只能在BeanDefinition自己去创建bean对象时才能去创建类)
  7. 如果allowEagerInit为false,并且BeanDefinition已经加载类了,或者是非懒加载的,或者允许提前加载类,并且不用必须提前初始化才能获取类型,那么就可以去进行匹配了;
  8. 不管是不是FactoryBean都会调用isTypeMatch()方法,只是传参不同;
  9. 根据isTypeMatch()方法的返回值判断BeanName是否需要放入集合中;
  10. 再往下这个循环,通过注释"Check manually registered singletons too.",我们可以得知,这里是校验不是通过扫描得到的Bean对象;符合要求也会放入集合中;

返回getBeanNamesForType()方法

isTypeMatch()方法

isTypeMatch()方法详解

java 复制代码
/**
 * Internal extended variant of {@link #isTypeMatch(String, ResolvableType)}
 * to check whether the bean with the given name matches the specified type. Allow
 * additional constraints to be applied to ensure that beans are not created early.
 *
 * @param name        the name of the bean to query
 * @param typeToMatch the type to match against (as a
 *                    {@code ResolvableType})
 * @return {@code true} if the bean type matches, {@code false} if it
 * doesn't match or cannot be determined yet
 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
 * @see #getBean
 * @see #getType
 * @since 5.2
 */
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
	boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);

	// Check manually registered singletons.
	Object beanInstance = getSingleton(beanName, false);
	if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
		if (beanInstance instanceof FactoryBean) {
			if (!isFactoryDereference) {
				// 调用factoryBean.getObjectType()
				Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
				return (type != null && typeToMatch.isAssignableFrom(type));
			} else {
				return typeToMatch.isInstance(beanInstance);
			}
		} else if (!isFactoryDereference) {  // 不是FactoryBean,就是普通Bean
			// 直接匹配
			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;
	} else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
		// null instance registered
		return false;
	}

	// No singleton instance found -> check bean definition.
	BeanFactory parentBeanFactory = getParentBeanFactory();
	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);
}

通过上述代码我们可以看到:

  1. 首先调用transformedBeanName()方法拿到真正的BeanName;
  2. 判断当前Bean是否是FactoryBean;
  3. 调用getSingleton()方法从单例池中获取Bean对象;
  4. 如果单例池中Bean对象不是null且不是NullBean,再判断是否是FactoryBean;
  5. 如果是FactoryBean,根据传进来的BeanName判断是找那个对象,&xxx调用getObjectType()方法拿到类型进行判断,xxx直接获取Bean对象进行类型匹配;
  6. 不是FactoryBean就是普通Bean对象,直接拿Bean对象进行类型匹配;
  7. 如果单例池中Bean对象不存在;判断单例池中包含这个BeanName且BeanDefinition不包含这个BeanName,说明类型没有匹配成功;
  8. 再往下由于逻辑过于繁琐,外加本篇篇幅确实太长,这个说一下大概逻辑:
  9. 从BeanDefinition中拿到类型去判断,再判断是否是FactoryBean,...... ,总之,匹配到返回true,匹配不到返回false;

返回doGetBeanNamesForType()方法

@value注解解析

@value注解解析

java 复制代码
// 获取@Value所指定的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
	if (value instanceof String) {
		// 占位符填充(${})
		String strVal = resolveEmbeddedValue((String) value);
		BeanDefinition bd = (beanName != null && containsBean(beanName) ?
				getMergedBeanDefinition(beanName) : null);
		// 解析Spring表达式(#{})
		value = evaluateBeanDefinitionString(strVal, bd);
	}
	// 将value转化为descriptor所对应的类型
	TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
	try {
		return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
	} catch (UnsupportedOperationException ex) {
		// A custom TypeConverter which does not support TypeDescriptor resolution...
		return (descriptor.getField() != null ?
				converter.convertIfNecessary(value, type, descriptor.getField()) :
				converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
	}
}

上述代码片段来自doResolveDependency()方法,我们可以看到:

  1. 如果有@value注解,值是字符串类型,
  2. 调用resolveEmbeddedValue()方法进行占位符解析,解析@value("${xxx}");
  3. 拿到占位符解析结果之后在调用evaluateBeanDefinitionString()方法,进行spring表达式解析,解析@value("#{xxx}");
  4. 最后将解析出来的值转换成属性对应的类型,进行返回;

返回doResolveDependency()方法

AutowiredMethodElement.inject()方法

AutowiredMethodElement.inject()方法详解

java 复制代码
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	// 如果pvs中已经有当前注入点的值了,则跳过注入
	if (checkPropertySkipping(pvs)) {
		return;
	}
	Method method = (Method) this.member;
	Object[] arguments;
	if (this.cached) {
		try {
			arguments = resolveCachedArguments(beanName);
		} catch (NoSuchBeanDefinitionException ex) {
			// Unexpected removal of target bean for cached argument -> re-resolve
			arguments = resolveMethodArguments(method, bean, beanName);
		}
	} else {
		arguments = resolveMethodArguments(method, bean, beanName);
	}
	if (arguments != null) {
		try {
			ReflectionUtils.makeAccessible(method);
			method.invoke(bean, arguments);
		} catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}
}

这里我们可以看到:

  1. 首先调用checkPropertySkipping()方法,如果在之前已经对当前注入点设置啦值,则跳过注入;(比如:实例化后等)
  2. 如果有缓存,调用resolveCachedArguments()方法,查找缓存;
  3. 没有缓存,调用resolveMethodArguments()方法

返回InjectionMetadata.inject()方法

resolveMethodArguments()方法

resolveMethodArguments()方法详解

java 复制代码
@Nullable
private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {
	int argumentCount = method.getParameterCount();
	Object[] arguments = new Object[argumentCount];
	DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
	Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
	Assert.state(beanFactory != null, "No BeanFactory available");
	TypeConverter typeConverter = beanFactory.getTypeConverter();

	// 遍历每个方法参数,找到匹配的bean对象
	for (int i = 0; i < arguments.length; i++) {
		MethodParameter methodParam = new MethodParameter(method, i);

		DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
		currDesc.setContainingClass(bean.getClass());
		descriptors[i] = currDesc;
		try {
			Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
			if (arg == null && !this.required) {
				arguments = null;
				break;
			}
			arguments[i] = arg;
		} catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
		}
	}
	synchronized (this) {
		if (!this.cached) {
			if (arguments != null) {
				DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
				registerDependentBeans(beanName, autowiredBeans);
				if (autowiredBeans.size() == argumentCount) {
					Iterator<String> it = autowiredBeans.iterator();
					Class<?>[] paramTypes = method.getParameterTypes();
					for (int i = 0; i < paramTypes.length; i++) {
						String autowiredBeanName = it.next();
						if (beanFactory.containsBean(autowiredBeanName) &&
								beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
							cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
									descriptors[i], autowiredBeanName, paramTypes[i]);
						}
					}
				}
				this.cachedMethodArguments = cachedMethodArguments;
			} else {
				this.cachedMethodArguments = null;
			}
			this.cached = true;
		}
	}
	return arguments;
}

这里我们可以看到:

  1. 遍历方法所有的参数;
  2. 经过一系列判断之后,调用AutowireCapableBeanFactory的resolveDependency方法,因为DefaultListableBeanFactory实现啦AutowireCapableBeanFactory接口,最终会走到DefaultListableBeanFactory的resolveDependency()方法
  3. 找到要注入的Bean对象之后会调用registerDependentBeans()方法,记录依赖关系;

返回AutowiredMethodElement.inject()方法;

findAutowiringMetadata()方法

findAutowiringMetadata()方法详解

java 复制代码
/**
 * 寻找注入点
 */
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
	// Fall back to class name as cache key, for backwards compatibility with custom callers.
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	// Quick check on the concurrent map first, with minimal locking.
	InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
	if (InjectionMetadata.needsRefresh(metadata, clazz)) {
		synchronized (this.injectionMetadataCache) {
			metadata = this.injectionMetadataCache.get(cacheKey);
			if (InjectionMetadata.needsRefresh(metadata, clazz)) {
				if (metadata != null) {
					metadata.clear(pvs);
				}
				// 解析注入点并缓存
				metadata = buildAutowiringMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

通过上述代码我们可以看到,首先会拿到BeanName,通过一系列逻辑判断,调用buildAutowiringMetadata()方法解析注入点,拿到注入点信息后放入缓存中,key是BeanName,Value是注入点信息;

回到查找注入点的方法;

回到给注入点赋值的方法

buildAutowiringMetadata()方法

buildAutowiringMetadata()方法详解

java 复制代码
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
	// 如果一个Bean的类型是String...,那么则根本不需要进行依赖注入
	if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
		return InjectionMetadata.EMPTY;
	}

	List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
	Class<?> targetClass = clazz;

	do {
		final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

		// 遍历targetClass中的所有Field
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			// field上是否存在@Autowired、@Value、@Inject中的其中一个
			MergedAnnotation<?> ann = findAutowiredAnnotation(field);
			if (ann != null) {
				// static filed不是注入点,不会进行自动注入
				if (Modifier.isStatic(field.getModifiers())) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation is not supported on static fields: " + field);
					}
					return;
				}

				// 获取 required 属性的值
				boolean required = determineRequiredStatus(ann);
				// 构造注入点
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});

		// 遍历targetClass中的所有Method
		ReflectionUtils.doWithLocalMethods(targetClass, method -> {

			Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
			if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
				return;
			}
			// method上是否存在@Autowired、@Value、@Inject中的其中一个
			MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
			if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
				// static method不是注入点,不会进行自动注入
				if (Modifier.isStatic(method.getModifiers())) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation is not supported on static methods: " + method);
					}
					return;
				}
				// set方法最好有入参
				if (method.getParameterCount() == 0) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation should only be used on methods with parameters: " +
								method);
					}
				}
				boolean required = determineRequiredStatus(ann);
				PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
				currElements.add(new AutowiredMethodElement(method, required, pd));
			}
		});

		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);

	return InjectionMetadata.forElements(elements, clazz);
}
	

通过上述代码,我们可以看到:

首先是一个判断,这个判断的作用的是,如果Bean类型是java.*.*或者是Ordered,会直接跳过,不会查找注入点;(java.lang.Integer、java.lang.String、......,JDK的对象不会进行依赖注入)

再往下我们看到的是一个do while 循环,循环体中有两大块逻辑,一块是遍历所有Field,一块是遍历所有Method:

  • 遍历所有Field
    • 调用findAutowiredAnnotation()方法,找到满足注入点的要求的field;
    • 再判断不是被static修饰的;
    • 调用determineRequiredStatus()方法获取required属性的值
    • 创建AutowiredFieldElement对象放入currElements(注入点缓存)中
  • 遍历所有Method
    • 通过BridgeMethodResolver.findBridgedMethod()判断当前Method是否是桥接方法,如果是找到原方法;
    • 调用findAutowiredAnnotation()方法,找到满足注入点的要求的Method;
    • 再判断不是被static修饰的;
    • 调用determineRequiredStatus()方法获取required属性的值;
    • 创建AutowiredMethodElement对象放入currElements(注入点缓存)中

回到findAutowiringMetadata()方法

findAutowiredAnnotation()方法

findAutowiredAnnotation()方法详解

java 复制代码
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
	MergedAnnotations annotations = MergedAnnotations.from(ao);
	for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
		MergedAnnotation<?> annotation = annotations.get(type);
		if (annotation.isPresent()) {
			return annotation;
		}
	}
	return null;
}

通过上述代码可以看到,循序autowiredAnnotationTypes集合中的注解,判断属性或者方法上是否有集合中的注解,autowiredAnnotationTypes集合中注解来源查看AutowiredAnnotationBeanPostProcessor()构造方法;

回到buildAutowiringMetadata()方法

AutowiredAnnotationBeanPostProcessor构造器

AutowiredAnnotationBeanPostProcessor()构造方法详解

java 复制代码
/**
 * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
 * standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
 * <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
 * if available.
 */
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
	this.autowiredAnnotationTypes.add(Autowired.class);
	this.autowiredAnnotationTypes.add(Value.class);
	try {
		this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
				ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
		logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
	} catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}

通过上述代码我们可以看到,AutowiredAnnotationBeanPostProcessor在创建的时候,构造器中会把@Autowired、@Value、@Inject注解放入autowiredAnnotationTypes中(Set<Class<? extends Annotation>> 集合);

回到findAutowiredAnnotation()方法

相关推荐
数据小爬虫@18 分钟前
Java爬虫实战:深度解析Lazada商品详情
java·开发语言
咕德猫宁丶20 分钟前
探秘Xss:原理、类型与防范全解析
java·网络·xss
F-2H2 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
苹果酱05672 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
武昌库里写JAVA2 小时前
【MySQL】7.0 入门学习(七)——MySQL基本指令:帮助、清除输入、查询等
spring boot·spring·毕业设计·layui·课程设计
_oP_i3 小时前
Pinpoint 是一个开源的分布式追踪系统
java·分布式·开源
mmsx3 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
武子康3 小时前
大数据-258 离线数仓 - Griffin架构 配置安装 Livy 架构设计 解压配置 Hadoop Hive
java·大数据·数据仓库·hive·hadoop·架构
豪宇刘4 小时前
MyBatis的面试题以及详细解答二
java·servlet·tomcat
秋恬意4 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis