Spring annotation @Autowired source code analysis

AutowiredAnnotationBeanPostProcessor is Spring's post-processor that handles @Autowired and @Value annotations.

1. Trigger method

  • postProcessMergedBeanDefinitionThe Spring container calls the AutowiredAnnotationBeanPostProcessor method after each bean is instantiated .
  • When Spring is instantiating each bean, populateBeanit calls the method for attribute injection postProcessPropertyValues.

2. Constructor

public AutowiredAnnotationBeanPostProcessor() {
	//后置处理器将处理@Autowire注解
	this.autowiredAnnotationTypes.add(Autowired.class);
	//后置处理器将处理@Value注解
	this.autowiredAnnotationTypes.add(Value.class);
	try {
		//后置处理器将处理javax.inject.Inject JSR-330注解
		this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
				ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
		logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
	}
	catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
	}

Third, the injection method

        //处理类中的属性,属性注入
	@Override
	public PropertyValues postProcessPropertyValues(
		PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

	//获取指定类中autowire相关注解的元信息
<1>	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		//对Bean的属性进行自动注入
		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;
	}

pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);This method is one of the concrete implementations called in the property injection populateBean .

The code at <1> is to obtain the corresponding annotation information from the bean. AutowiredAnnotationBeanPostProcessorHere, it is to find the fields annotated with @Value and @Autowired, and then encapsulate the relevant information InjectionMetadata. There is still a lot of logic here, which will be introduced later, so I won't say much here.

Look directly at the specific injection logic:

//InjectionMetadata.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()) {
		boolean debug = logger.isDebugEnabled();
		//遍历每个字段 注入
		for (InjectedElement element : elementsToIterate) {
			if (debug) {
				logger.debug("Processing injected element of bean '" + beanName + "': " + element);
			}
			element.inject(target, beanName, pvs);
		}
	}
	}

This is not the real injection method, we continue to trackelement.inject(target, beanName, pvs);

//InjectionMetadata.java

protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
		throws Throwable {

	if (this.isField) {
		Field field = (Field) this.member;
		ReflectionUtils.makeAccessible(field);
		field.set(target, getResourceToInject(target, requestingBeanName));
	}
	else {
		if (checkPropertySkipping(pvs)) {
			return;
		}
		try {
			Method method = (Method) this.member;
			ReflectionUtils.makeAccessible(method);
			method.invoke(target, getResourceToInject(target, requestingBeanName));
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}
		}

This is element.inject()the original method, and it also has two methods implemented by subclasses, as shown in the figure:

As can be seen from the method name, one is for field injection and the other is for method injection. And both methods are AutowiredAnnotationBeanPostProcessorconcrete implementations.

3.1, field injection

Let's first look at the field injection:

//AutowiredAnnotationBeanPostProcessor.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) {
			//从缓存中获取字段值value
			value = resolvedCachedArgument(beanName, this.cachedFieldValue);
		}
		//没有缓存
		else {
			//创建一个字段依赖描述符
			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();
			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) {
					//字段值不为null,并且required属性为true
					if (value != null || this.required) {
						this.cachedFieldValue = desc;
						//为指定Bean注册依赖Bean
						registerDependentBeans(beanName, autowiredBeanNames);
						if (autowiredBeanNames.size() == 1) {
							String autowiredBeanName = autowiredBeanNames.iterator().next();
							//如果容器中有指定名称的Bean对象
							if (beanFactory.containsBean(autowiredBeanName)) {
								//依赖对象类型和字段类型匹配,默认按类型注入
								if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									//创建一个依赖对象的引用,同时缓存
									this.cachedFieldValue = new ShortcutDependencyDescriptor(
											desc, autowiredBeanName, field.getType());
								}
							}
						}
					}
					//如果获取的依赖关系为null,且获取required属性为false
					else {
						//将字段值的缓存设置为null
						this.cachedFieldValue = null;
					}
					//容器已经对当前字段的值缓存
					this.cached = true;
				}
			}
		}
		//如果字段值不为null
		if (value != null) {
			//显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
			ReflectionUtils.makeAccessible(field);
			//为字段赋值
			field.set(bean, value);
		}
	}

This code is easy to understand, get the value to be injected from the annotation @Value/@Autowired, and then use reflection to set it into the field.
The point is how to get the value to be injected from the annotation, let's look at the core codevalue = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

//DefaultListableBeanFactory.java

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

	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
	if (Optional.class == descriptor.getDependencyType()) {
		return createOptionalDependency(descriptor, requestingBeanName);
	}
	else if (ObjectFactory.class == descriptor.getDependencyType() ||
			ObjectProvider.class == descriptor.getDependencyType()) {
		return new DependencyObjectProvider(descriptor, requestingBeanName);
	}
	else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
		return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
	}
	else {
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		if (result == null) {
			//真正获取值的代码
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
	}

To track:

//DefaultListableBeanFactory.java

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

	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		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);
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			return (descriptor.getField() != null ?
					converter.convertIfNecessary(value, type, descriptor.getField()) :
					converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
		}

		//如果标识@Autowired注解的属性是集合类型,Array,Collection,Map,
		// 从这个方法获取@Autowired里的值
<1>		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}

		//如果标识@Autowired注解的属性是非集合类型,
		// 从这个方法获取@Autowired里的值
<2>		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		//如果没有符合该类型的Bean
		if (matchingBeans.isEmpty()) {
			//是否是必须的
			if (isRequired(descriptor)) {
				//抛出异常
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		//如果符合该类型的Bean有多个
		if (matchingBeans.size() > 1) {
			//挑选出最优解
<3>			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					//抛出异常
					return descriptor.resolveNotUnique(type, 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();
		}

		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		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);
	}
	}

This code looks long, but it's actually quite easy to understand. The general process is:
get the matching beans from the IOC container according to the field type, if there are more than one, select the best one.

Let's look at the specific logic below.

3.1.1, <1>: @Autowired injects collection array

Let's first look at the logic of @Autowired injection into the collection array:

//DefaultListableBeanFactory.java

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

	Class<?> type = descriptor.getDependencyType();
	//如果@Autowired标识的是数组类型的属性
	if (type.isArray()) {
		//获取数组的内容类型
		Class<?> componentType = type.getComponentType();
		ResolvableType resolvableType = descriptor.getResolvableType();
		Class<?> resolvedArrayType = resolvableType.resolve();
		if (resolvedArrayType != null && resolvedArrayType != type) {
			type = resolvedArrayType;
			componentType = resolvableType.getComponentType().resolve();
		}
		if (componentType == null) {
			return null;
		}
		//通过类型去IOC容器内择取符合的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());
		//将得到的Bean的候选者们转换为属性类型,如从set转换为Array,List等
		Object result = converter.convertIfNecessary(matchingBeans.values(), type);
		if (getDependencyComparator() != null && result instanceof Object[]) {
			Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
		}
		return result;
	}
	else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
		//获取Collection的泛型
		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 (getDependencyComparator() != null && result instanceof List) {
			Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
		}
		return result;
	}
	else if (Map.class == type) {
		ResolvableType mapType = descriptor.getResolvableType().asMap();
		Class<?> keyType = mapType.resolveGeneric(0);
		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;
	}
	}

3.1.2, <2>: @Autowired injects non-collection array

//DefaultListableBeanFactory.java

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

	//从IOC容器中获取所有的符合类型的BeanName,存入候选数组
	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
	//首先从容器自身注册的依赖解析来匹配,Spring容器自身注册了很多Bean的依赖,
	//当使用者想要注入指定类型的Bean时,会优先从已注册的依赖内寻找匹配
	for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
		if (autowiringType.isAssignableFrom(requiredType)) {
			Object autowiringValue = this.resolvableDependencies.get(autowiringType);
			autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
			//如果注册的依赖Bean类型是指定类型的实例或是其父类,接口,则将其作为候选者,注册依赖的类型不会重复
			if (requiredType.isInstance(autowiringValue)) {
				result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
				break;
			}
		}
	}
	//遍历候选数组
	for (String candidate : candidateNames) {
		//候选Bean不是自引用(即要注入的类不能是类本身,会触发无限递归注入)
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}
	if (result.isEmpty() && !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)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		if (result.isEmpty()) {
			// 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;
	}

This code comment has been written very clearly, let's continue to look at the addCandidateEntrymethod, which is to put the Bean instance into the candidate set

//DefaultListableBeanFactory.java

private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
		DependencyDescriptor descriptor, Class<?> requiredType) {

	//当@Autowired标识的是容器类型的属性,生成的依赖描述类型是MultiElementDescriptor ,
	//因此所有的候选者均是合格的,所以会当场实例化他们。而如果属性的类型非容器,那么可能是多个候选者中挑一个,
	//此时实例化他们所有就不合适了,最终会把合格的那个实例化,如果没有合格的则不实例化,
	//提前实例化对Bean的很多方面有影响,比如AOP,EarlyReference等 */
	if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) {
		Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
		candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
	}
	else {
		candidates.put(candidateName, getType(candidateName));
	}
	}

Here the doGetBean() method will be called to instantiate the Bean

<3>: Select the optimal solution from multiple candidates

If there are multiple beans obtained from the IOC container according to the type, then the determineAutowireCandidate(matchingBeans, descriptor)method needs to be called to select the optimal solution.
Code:

//DefaultListableBeanFactory.java

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
	Class<?> requiredType = descriptor.getDependencyType();
	//根据@Primary注解来择取最优解
	String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
	if (primaryCandidate != null) {
		return primaryCandidate;
	}
	//根据@Order,@PriorityOrder,及实现Order接口的序号来择取最优解
	String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
	if (priorityCandidate != null) {
		return priorityCandidate;
	}
	// Fallback
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateName = entry.getKey();
		Object beanInstance = entry.getValue();
		//如果通过以上两步都不能选择出最优解,则使用最基本的策略
		//首先如果这个类型已经由Spring注册过依赖关系对,则直接使用注册的对象,
		//候选者集合是LinkedHashMap,有序Map集合,容器注册的依赖对象位于LinkedHashMap的起始位置
		//如果没有注册过此类型的依赖关系,则根据属性的名称来匹配,、
		//如果属性名称和某个候选者的Bean名称或别名一致,那么直接将此Bean作为最优解
		if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
				matchesBeanName(candidateName, descriptor.getDependencyName())) {
			return candidateName;
		}
	}
	return null;
	}

This part of the logic is relatively simple, and the summary is 3 steps:

  • Select the optimal solution according to the @Primary annotation
  • Select the optimal solution according to @Order, @PriorityOrder, and the serial number that implements the Order interface
  • According to Spring default rules

Let's analyze these steps one by one, let's look at the first one:
choose the optimal solution according to the @Primary annotation

//DefaultListableBeanFactory.java

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();
		//候选者可以是父容器内的标识了@Primary的Bean,也可以是当前容器的。SpringMVC容器将Spring容器作为父容器
		if (isPrimary(candidateBeanName, beanInstance)) {
			if (primaryBeanName != null) {
				boolean candidateLocal = containsBeanDefinition(candidateBeanName);
				boolean primaryLocal = containsBeanDefinition(primaryBeanName);
				//此处确保同一个容器中同一个类型的多个Bean最多只有一个Bean标识了@Primary
				if (candidateLocal && primaryLocal) {
					throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
							"more than one 'primary' bean found among candidates: " + candidates.keySet());
				}
				//如果上一个@Primary的Bean是父容器的,则用当前容器的候选者覆盖之前的@Primary的Bean
				else if (candidateLocal) {
					primaryBeanName = candidateBeanName;
				}
			}
			else {
				primaryBeanName = candidateBeanName;
			}
		}
	}
	return primaryBeanName;
	}

Then look at the second one:
according to @Order, @PriorityOrder

//DefaultListableBeanFactory.java

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();
		Integer candidatePriority = getPriority(beanInstance);
		if (candidatePriority != null) {
			//不能同时存在两个最高优先级的序号
			if (highestPriorityBeanName != null) {
				if (candidatePriority.equals(highestPriority)) {
					throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
							"Multiple beans found with the same priority ('" + highestPriority +
							"') among candidates: " + candidates.keySet());
				}
				//使用优先级序号最小的Bean作为最优解
				else if (candidatePriority < highestPriority) {
					highestPriorityBeanName = candidateBeanName;
					highestPriority = candidatePriority;
				}
			}
			else {
				highestPriorityBeanName = candidateBeanName;
				highestPriority = candidatePriority;
			}
		}
	}
	return highestPriorityBeanName;
	}

Summary :
At this point, the source code injected by the @Autowired field has been analyzed.

Next we look at the method injection:

3.2, method injection

//DefaultListableBeanFactory.java

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	//如果属性被显式设置为skip,则不进行注入
	if (checkPropertySkipping(pvs)) {
		return;
	}
	//获取注入元素对象
	Method method = (Method) this.member;
	Object[] arguments;
	//如果容器对当前方法缓存
	if (this.cached) {
		// Shortcut for avoiding synchronization...
		//获取缓存中指定Bean名称的方法参数
		arguments = resolveCachedArguments(beanName);
	}
	//如果没有缓存
	else {
		//获取方法的参数列表
		Class<?>[] paramTypes = method.getParameterTypes();
		//创建一个存放方法参数的数组
		arguments = new Object[paramTypes.length];
		DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
		Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
		Assert.state(beanFactory != null, "No BeanFactory available");
		//获取容器的类型转换器
		TypeConverter typeConverter = beanFactory.getTypeConverter();
		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;
				}
				//根据容器中Bean定义解析依赖关系,获取方法参数依赖对象
				arguments[i] = arg;
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
			}
		}
		//线程同步,以确保容器中数据一致性
		synchronized (this) {
			//如果当前方法没有被容器缓存
			if (!this.cached) {
				//如果方法的参数列表不为空
				if (arguments != null) {
					//为容器中缓存方法参数的对象赋值
					Object[] cachedMethodArguments = new Object[paramTypes.length];
					for (int i = 0; i < arguments.length; i++) {
						cachedMethodArguments[i] = descriptors[i];
					}
					//为指定Bean注册依赖Bean
					registerDependentBeans(beanName, autowiredBeans);
					//如果依赖对象集合大小等于方法参数个数
					if (autowiredBeans.size() == paramTypes.length) {
						Iterator<String> it = autowiredBeans.iterator();
						//为方法参数设置依赖对象
						for (int i = 0; i < paramTypes.length; i++) {
							String autowiredBeanName = it.next();
							//如果容器中存在指定名称的Bean对象
							if (beanFactory.containsBean(autowiredBeanName)) {
								//如果参数类型和依赖对象类型匹配
								if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
									//创建一个依赖对象的引用,复制给方法相应的参
									cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
											descriptors[i], autowiredBeanName, paramTypes[i]);
								}
							}
						}
					}
					this.cachedMethodArguments = cachedMethodArguments;
				}
				//如果方法参数列表为null,则设置容器对该方法参数的缓存为null
				else {
					this.cachedMethodArguments = null;
				}
				//设置容器已经对该方法缓存
				this.cached = true;
			}
		}
	}
	//如果方法参数依赖对象不为null
	if (arguments != null) {
		try {
			//使用JDK的反射机制,显式设置方法的访问控制权限为允许访问
			ReflectionUtils.makeAccessible(method);
			//调用Bean的指定方法
			method.invoke(bean, arguments);
		}
		catch (InvocationTargetException ex){
			throw ex.getTargetException();
		}
	}
		}

Summarize:

The principle of the @Autowired annotation is explained in one sentence:
it is to first find all the matching beans according to the type from the IOC container, and then select the most matching beans according to @Primary, @Order, @PriorityOrder or Spring default rules, and use reflection injection. into the field.

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324032092&siteId=291194637