Spring原始碼解析——依賴注入(二)

還沒禿的小菜雞發表於2020-10-22

前面說到Spring 通過bytype注入,留下了一些沒有訴說,現在來詳細看看

protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);

		// 找到有對應set方法的屬性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// Don't try autowiring by type for type Object: never makes sense,
				// even if it technically is a unsatisfied, non-simple property.
				//這裡是判斷是你的屬性描述器,也就是說你的set方法的引數的型別不能是Object
				//因為如果setUserService(Object userService),那麼像這個方法,如果是Object,spring根本不知道你要注入那個bean
				//所以不能是Object
				if (Object.class != pd.getPropertyType()) {
					// set方法中的引數資訊
					//根據屬性描述器獲取這個set方法的引數資訊
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);

					/**
					 *
					 * 根據方法的引數MethodParameter獲取一個bean
					 * 到這裡知道這個方法是byType,byType的原理是根據你的set方法的引數型別得到一個bean,所以這裡是通過
					 * set方法的引數比如setUserService(UserService uservice)中的UserService來構建一個依賴描述器
					 * 這個依賴描述器得到過後,根據這個依賴描述器和其他一些引數得到一個bean
					 */
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);

					// 根據型別找bean,這就是byType
					//簡單來說就是根據依賴描述器通過下面這個方法得到一個Bean,然後注入到pvs中
					//後面說
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isTraceEnabled()) {
							logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			} catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}
  1. 找到有對應set方法的屬性
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
		Set<String> result = new TreeSet<>();
		PropertyValues pvs = mbd.getPropertyValues(); // 在BeanDefinition中新增的屬性和值,
		//
		PropertyDescriptor[] pds = bw.getPropertyDescriptors();

		// 對類裡所有的屬性進行過濾,確定哪些屬性是需要進行自動裝配的
		for (PropertyDescriptor pd : pds) {
			// 屬性有set方法,並且
			// 沒有通過DependencyCheck排除,並且
			// 沒有在BeanDefinition中給該屬性賦值,並且
			// 屬性的型別不是簡單型別
			if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
					!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
				result.add(pd.getName());
			}
		}

		// 返回過濾之後的結果,後續只對這些屬性進行自動裝配
		return StringUtils.toStringArray(result);
	}
  1. 得到屬性描述getPropertyDescriptor,根據屬性描述器獲取這個set方法的引數資訊getWriteMethodParameter,然後根據方法的引數MethodParameter構建一個依賴描述器通過AutowireByTypeDependencyDescriptor
  2. 根據依賴描述器得到一個Bean通過resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
		// DependencyDescriptor表示一個依賴,可以是一個屬性欄位,可能是一個構造方法引數,可能是一個set方法引數
		// 根據descriptor去BeanFactory中找到bean

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

		// 如果依賴的型別是Optional
		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 Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {

			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);

			if (result == null) {
				// 通過解析descriptor找到bean物件
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}
  • 判斷descriptor.getDependencyType()的型別
  • 若果依賴描述上存在@Lazy註解,那麼會生成一個代理物件,然後返回包裝成Optional否則呼叫doResolveDependen

通過解析依賴描述找到bean物件result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)

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

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			// 如果DependencyDescriptor是一個ShortcutDependencyDescriptor,
			// 那麼會直接理解beanName從beanFactory中拿到一個bean,
			// 在利用@Autowired註解來進行依賴注入時會利用ShortcutDependencyDescriptor來進行依賴注入的快取,
			// 表示當解析完某個依賴資訊後,會把依賴的bean的beanName快取起來
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			// 獲取descriptor具體的型別,某個Filed的型別或某個方法引數的型別
			Class<?> type = descriptor.getDependencyType();

			// 獲取@Value註解中所配置的值
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); // 是否通過@Value註解指定了值
			if (value != null) {
				if (value instanceof String) {
					// 先進行佔位符的填充,解析"$"符號
					String strVal = resolveEmbeddedValue((String) value);

					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);

					// 解析Spring EL表示式,解析"#"符號(可以進行運算,可以寫某個bean的名字)
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					// 把value從descriptor.getTypeDescriptor()型別轉化為type類
					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()));
				}
			}

			// 沒有使用@Value註解
			// 要注入的依賴的型別是不是一個Map、Array、Collection
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			// 通過type找,可能找到多個
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			// 根據type找到了多個
			if (matchingBeans.size() > 1) {
				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();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
				// 呼叫beanFactory.getBean(beanName);建立bean物件
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

  • 先判斷是不是Shortcut,如果是那麼可以理解beanName直接從beanFactory中拿到一個bean
// 如果DependencyDescriptor是一個ShortcutDependencyDescriptor,
			// 那麼會直接理解beanName從beanFactory中拿到一個bean,
			// 在利用@Autowired註解來進行依賴注入時會利用ShortcutDependencyDescriptor來進行依賴注入的快取,
			// 表示當解析完某個依賴資訊後,會把依賴的bean的beanName快取起來
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

//------------------------------------------------------------------------------
@Override
		public Object resolveShortcut(BeanFactory beanFactory) {
			return beanFactory.getBean(this.shortcut, this.requiredType);
		}
  • 判斷@Value註解是否存在,如果存在獲取並解析descriptor上的@Value註解,並進行解析返回
// 獲取@Value註解中所配置的值
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); // 是否通過@Value註解指定了值
			if (value != null) {
				if (value instanceof String) {
					// 先進行佔位符的填充,解析"$"符號
					String strVal = resolveEmbeddedValue((String) value);

					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);

					// 解析Spring EL表示式,解析"#"符號(可以進行運算,可以寫某個bean的名字)
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					// 把value從descriptor.getTypeDescriptor()型別轉化為type類
					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的型別
  • descriptor的型別為Collection,或者map則直接返回map的value或者map
// 沒有使用@Value註解
			// 要注入的依賴的型別是不是一個Map、Array、Collection
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}
  • 呼叫findAutowireCandidates(beanName, type, descriptor),該方法返回一個Map,表示會根據type去找bean,Map的key為beanName,Map的value為物件(注意可能是bena的物件,也可能是某個bean的class物件,因為該方法只負責根據型別找到對應的bean,如果該bean還沒有例項化,那麼該方法不負責去例項化,只返回該bean對應的Class物件,表示這個bean也是結果之一)
// 根據requiredType尋找自動匹配的候選者bean
	protected Map<String, Object> findAutowireCandidates(
			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
		// 根據requiredType找到candidateNames,表示根據type找到了候選beanNames
		// Ancestors是祖先的意思,所以這個方法是去當前beanfactory以及祖先beanfactory中去找型別為requiredType的bean的名字
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);

		// 先從resolvableDependencies
		for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
			Class<?> autowiringType = classObjectEntry.getKey();
			// requiredType是autowiringType的子類
			// 也就是,某個bean中的屬性的型別是requiredType,是resolvableDependencies中的子類
			if (autowiringType.isAssignableFrom(requiredType)) {
				//  是resolvableDependencies中的子類所存的物件
				Object autowiringValue = classObjectEntry.getValue();
				autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
				if (requiredType.isInstance(autowiringValue)) {
					// 把resolvableDependencies中儲存的物件作為當前屬性的一個候選者
					result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
					break;
				}
			}
		}

		// 對候選bean進行過濾,首先候選者不是自己,然後候選者是支援自動注入給其他bean的
		for (String candidate : candidateNames) {
			// isAutowireCandidate方法中會去判斷候選者是否和descriptor匹配
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		if (result.isEmpty()) {
			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);
				}
			}
			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;
	}
  • 判斷根據type有沒有找到bean
  • 如果沒有找到,判斷是不是isRequired
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}
  • 如果找到判斷是否超過一個,如果只有一個則則直接返回該bean,如果是Class物件,則呼叫getBean生成該bean物件
  • 超過一個則呼叫determineAutowireCandidate(matchingBeans, descriptor)
// 根據type找到了多個
			if (matchingBeans.size() > 1) {
				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();
			}

在找到多個的情況下呼叫determineAutowireCandidate(matchingBeans, descriptor)

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
		Class<?> requiredType = descriptor.getDependencyType();

		// 取@Primary的bean
		String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
		if (primaryCandidate != null) {
			return primaryCandidate;
		}

		// 取優先順序最高的bean
		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();
			if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
					// 根據屬性名確定
					matchesBeanName(candidateName, descriptor.getDependencyName())) {
				return candidateName;
			}
		}
		return null;
	}
  • 從多個Bean中選擇被@Primary標註了的Bean,如果有多個@Primary會報錯
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
		if (primaryCandidate != null) {
			return primaryCandidate;
		}

//---------------------------------------------------------------------
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();
			// 當前candidateBean是否@Primary
			if (isPrimary(candidateBeanName, beanInstance)) {
				if (primaryBeanName != null) {
					boolean candidateLocal = containsBeanDefinition(candidateBeanName);
					boolean primaryLocal = containsBeanDefinition(primaryBeanName);
					if (candidateLocal && primaryLocal) {
						throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
								"more than one 'primary' bean found among candidates: " + candidates.keySet());
					}
					else if (candidateLocal) {
						primaryBeanName = candidateBeanName;
					}
				}
				else {
					primaryBeanName = candidateBeanName;
				}
			}
		}
		return primaryBeanName;
	}
  • 如果沒有@Primary,那麼則看Bean上是否通過@Priority定義了優先順序,如果定義了則獲取優先順序最高的Bean
// 取優先順序最高的bean
		String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
		if (priorityCandidate != null) {
			return priorityCandidate;
		}
  • 如果沒有優先順序,那麼使用descriptor.getDependencyName()來確定一個唯一的Bean
  • 判斷是否找到唯一的Bean
  • 找到後如果不是Class物件直接返回,如果是就通過getBean獲取
  • 如果沒有找到,判斷是否isRequired,如果是報錯,不是就返回null
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
			String candidateName = entry.getKey();
			Object beanInstance = entry.getValue();
			if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
					// 根據屬性名確定
					matchesBeanName(candidateName, descriptor.getDependencyName())) {
				return candidateName;
			}
		}
  1. 整體流程
    在這裡插入圖片描述

相關文章