Spring源码解析——依赖注入(二)

前面说到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. 整体流程
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值