Spring源码分析四:bean的属性注入 - populateBean

一、前言

本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。在阅读过程中也创建了一些衍生文章,衍生文章的意义是因为自己在看源码的过程中,部分知识点并不了解或者对某些知识点产生了兴趣,所以为了更好的阅读源码,所以开设了衍生篇的文章来更好的对这些知识点进行进一步的学习。


这篇文章应该是接着 Spring源码分析二:单例bean的获取 - createBean 的继续分析过程。
本文主要是分析Spring 具体创建bean的过程。

本文的分析代码在 AbstractAutowireCapableBeanFactory#doCreateBean 方法中


本文衍生篇:

  1. Spring源码分析衍生篇五:AutowiredAnnotationBeanPostProcessor

二、整体逻辑

先看一下之前的步骤
在到达这一步之前, AbstractAutowireCapableBeanFactory#createBeanInstance 已经创建了bean,相应的缓存也已经添加。开始进行属性注入。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    
    
		if (bw == null) {
    
    
			// 没有属性抛出异常
			if (mbd.hasPropertyValues()) {
    
    
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
    
    
				// Skip property population phase for null instance.
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		// 这里调用了 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation方法
		// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    
    
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;						
					// 返回值为是否继续填充bean
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    
    
						return;
					}
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		// 根据名称或类型自动注入
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    
    
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    
    
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    
    
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}
		// 后处理器已经初始化
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		// 需要依赖检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
    
    
			if (pvs == null) {
    
    
				pvs = mbd.getPropertyValues();
			}
			// 调用了InstantiationAwareBeanPostProcessor.postProcessProperties 方法 和 postProcessPropertyValues 方法 来进行设值后处理
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;					
					// 调用设值
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
    
    
						if (filteredPds == null) {
    
    
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
    
    
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		// 如果需要检查
		if (needsDepCheck) {
    
    
			if (filteredPds == null) {
    
    
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			// 依赖检查,对应 depends-on 属性,3.0 已弃用
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
    
    
			// 将属性应用到bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

从上看下来,整个流程如下:

  1. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法,可以决定程序是否继续进行属性填充。只要有一个 InstantiationAwareBeanPostProcessor 返回false,都会终止属性填充的过程。
  2. 根据注入类型(name或type),提取依赖的bean,并统一存入到 propertyValues 中。
  3. 应用 InstantiationAwareBeanPostProcessor.postProcessProperties 和 InstantiationAwareBeanPostProcessor.postProcessPropertyValues 方法,对属性获取完毕填充前对属性的再次处理。
  4. 将所有 propertyValues 中的属性填充至 BeanWrapper 中。

在这里方法里按照如下顺序调用了后处理器

  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation :
  • InstantiationAwareBeanPostProcessor.postProcessProperties :
  • InstantiationAwareBeanPostProcessor.postProcessPropertyValues : 已过时

三、关键解析

1. 属性填充判断

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    
    
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    
    
						return;
					}
				}
			}
		}

如下,这里调用了InstantiationAwareBeanPostProcessor 后处理器的postProcessAfterInstantiation 方法来决定是否继续注入属性。关于后处理器的内容,详参:Spring源码分析衍生篇四:后处理器 BeanPostProcessor。这里就不再赘述。

2. 自动装配

Spring 定义的自动装配的种类有四种:

扫描二维码关注公众号,回复: 11960608 查看本文章
  • AUTOWIRE_NO : 默认值,不进行自动装配
  • AUTOWIRE_BY_NAME : 根据 name 自动装配
  • AUTOWIRE_BY_TYPE : 根据type 自动装配
  • AUTOWIRE_CONSTRUCTOR : 根据构造函数自动装配

在下面这段代码中,对 AUTOWIRE_BY_NAME 类型和 AUTOWIRE_BY_TYPE 的 种类进行自动装配。

		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    
    
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    
    
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    
    
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

这一段代码的目的是,如果bean在声明的时候指定了自动注入类型是 byName或者byType,则会根据这个规则,对 bean内部的排除某些特定的属性(排除规则后面详解), 进行byName 或者 byType的自动装配。

2.1 自动装配 - autowireByName

	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    
    
		// 寻找bw中需要依赖注入的属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
    
    
			// 检查缓存bean 中是否有当前bean
			if (containsBean(propertyName)) {
    
    
				// 递归初始化bean,会调用doGetBean 来 获取bean
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				// 注册依赖,将依赖关系保存到 Map<String, Set<String>> dependentBeanMapdependentBeanMap 中,key是 bean,value是 转化后的 propertyName
				registerDependentBean(propertyName, beanName);
				if (logger.isTraceEnabled()) {
    
    
					logger.trace("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
    
    
				// 找不到则不处理
				if (logger.isTraceEnabled()) {
    
    
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

可以看到,byName 的处理逻辑很简单,一句话概括,获取需要注入的bean然后递归调用getBean获取bean进行注入。

2.2. 自动装配 - autowireByType

byType 的装配和 byName 对我们感觉来说似乎没什么差异,但是在实际实现上却截然不同,代码也复杂的多。具体代码如下:

		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);
		// 寻找 bw中需要依赖注入的属性
		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.
				if (Object.class != pd.getPropertyType()) {
    
    
					// 获取指定属性的 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);
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					// 解析指定beanName 的属性所匹配的值,并把解析到的属性名存储在 autowiredBeanNames  中
					// 当属性存在多个封装bean时,如 @Autowired List<Bean> beans,会找到所有的匹配Bean 类型的bean并将其注入。
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
    
    
						// 添加到待注入的bean列表中
						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);
			}
		}
	}

可以看到,这里面的主要的逻辑被封装到了 resolveDependency 方法中,我们下面来看看DefaultListableBeanFactory#resolveDependency 方法的具体实现。(resolveDependency 在 AutowiredAnnotationBeanPostProcessor 中注入处理 @Autowired 注入的时候也调用了,具体请看衍生篇)

2.2.1 DefaultListableBeanFactory#resolveDependency

	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 Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
    
    
			// 处理bean是否懒加载,如果懒加载,创建一个代理对象注入bean
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
    
    
				// 针对一般类型的通用
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

上面的逻辑比较清晰,对一些特殊的类型进行特殊处理,一般的通用处理都会调用 doResolveDependency 方法,所以下面再来看看
DefaultListableBeanFactory#doResolveDependency 方法,代码如下。

2.2.2 DefaultListableBeanFactory#doResolveDependency

	@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    
    
  // 只有ShortcutDependencyDescriptor实现了resolveShortcut方法,返回了非空值。目前版本代码只在AutowiredFieldElement、AutowiredMethodElement类中使用到,也即是说,只有解析@Autowired、@Value注解的元素才会用到,目的是为了将解析结果缓存起来,避免重复解析
		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
    
    
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
    
    
				return shortcut;
			}
			// 获取 依赖的类型
			Class<?> type = descriptor.getDependencyType();
			// 取值注解中的value属性中的值,这里取出的值是未经修改的值,即带有 ${} 标签的值。如果descriptor未被@Value标注,则返回null
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
    
    
				// 如果value不为null,
				if (value instanceof String) {
    
    
					// 处理占位符如${},做占位符的替换(不解析SP EL表达式)
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					//		解析SP EL(如#{})
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
    
    
					// 类型转换,把解析出来的结果转成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()));
				}
			}
			// 对集合类型进行处理,包括,Array、Collection、Map
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
    
    
				return multipleBeans;
			}
			// 调用查找所有类型为type的实例,存放在matchingBeans <beanName, bean> (在 resolveMultipleBeans 方法中也是核心也是调用该方法)
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
    
    
				if (isRequired(descriptor)) {
    
    
				// 如果没有找到,并且bean 并标注为 required = true, 则抛出NoSuchBeanDefinitionException异常
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;
			// 如果找到了不止一个匹配的bean,Spring 按照一定规则进行挑选
			if (matchingBeans.size() > 1) {
    
    
			// 按以下顺序,找到符合条件的就直接返回
            // 1. 挑选出被标识为primary的bean
            // 2. 挑选标识了@Priority,且先级级最高的bean。可以不标识,一旦标识,不允许同一优先级的存在
            // 3. fallback,依赖的名称与matchingBeans中任意一Key匹配
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
    
    
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
    
    
						// 非集合类,找到了多个符合条件的Bean,抛出异常
						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) {
    
    
			 	// 将待装配的Bean名称放入autowiredBeanNames集合里
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
    
    
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
    
    
				if (isRequired(descriptor)) {
    
    
				// 如果 result 是 NullBean类型,且 required = true,则抛出异常
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			// 类型校验,确保类型与解析出来的Bean实例能够匹配
			if (!ClassUtils.isAssignableValue(type, result)) {
    
    
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
    
    
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}
	
	...
	 
	protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
    
    
		// 获取类型
		Class<?> requiredType = descriptor.getDependencyType();
		// 获取 primary 的 候选beanName
		String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
		if (primaryCandidate != null) {
    
    
			return primaryCandidate;
		}
		// 获取 Priority 最高(优先级最高的) beanName
		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;
	}

2.2.3 DefaultListableBeanFactory#resolveMultipleBeans

这个方法是用来处理 数组、Collection、Map 类型的注入。具体实现如下:

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

		final Class<?> type = descriptor.getDependencyType();
		// 如果是 StreamDependencyDescriptor 类型,则返回流的形式
		if (descriptor instanceof StreamDependencyDescriptor) {
    
    
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (autowiredBeanNames != null) {
    
    
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			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;
			}
			// 根据属性类型找到beanFactory 中所有类型的匹配bean
			// 返回值构成 : key=匹配的beanName, value=beanName 对应的实例化bean,通过 getBean(beanName)获取。
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
					new MultiElementDescriptor(descriptor));
			// 如果是未找到匹配的bean,则返回null,
			if (matchingBeans.isEmpty()) {
    
    
				return null;
			}
			if (autowiredBeanNames != null) {
    
    
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			// 进行类型转换,将bean 转换为对应的type 类型。
			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;
		}
		// 对 Collection 类型的处理,逻辑基本同上,这里不再赘述
		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;
		}
		// 对map类型的处理,逻辑类似上面
		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;
		}
	}

可以看到的是,如果是集合类型,内部的核心方法也是 findAutowireCandidates 方法。所以下面还是来看 DefaultListableBeanFactory#findAutowireCandidates 方法。

2.2.4.DefaultListableBeanFactory#findAutowireCandidates

	protected Map<String, Object> findAutowireCandidates(
			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
    
    
		// 根据 Class 类型,找到对应的候选beanName,
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
		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;
				}
			}
		}
		// 遍历候选的beanName
		for (String candidate : candidateNames) {
    
    
			// 不是自引用 && 允许被注入(autowire-candidate 标签指定) 
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
    
    
				// 将结果添加到result中
				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;
	}
	
	...
	
	private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
			DependencyDescriptor descriptor, Class<?> requiredType) {
    
    
		// 根据类型判断,如果是MultiElementDescriptor,获取后保存到候选列表中
		if (descriptor instanceof MultiElementDescriptor) {
    
    
			Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
			if (!(beanInstance instanceof NullBean)) {
    
    
				candidates.put(candidateName, beanInstance);
			}
		}
		// 如果 单例缓存中存在 ||  是 StreamDependencyDescriptor  的类型 &&  order = true
		else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
				((StreamDependencyDescriptor) descriptor).isOrdered())) {
    
    
			// 调用了beanFacotory.getBean 方法获取bean
			Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
			// 保存起来
			candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
		}
		else {
    
    
			// getType 调用了beanFacotory.getBean 方法
			candidates.put(candidateName, getType(candidateName));
		}
	}

2.3 排除规则 - unsatisfiedNonSimpleProperties

autowireByNameautowireByType方法中,都有如下一行代码

String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

unsatisfiedNonSimpleProperties 方法中,对Bean 的属性进行了过滤,得到了需要自动装配的属性。我们来详细看看里面的内容。

	protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
    
    
		Set<String> result = new TreeSet<>();
		// 获取bean 的property 属性
		PropertyValues pvs = mbd.getPropertyValues();
		// 获取 bw 中的属性描述
		PropertyDescriptor[] pds = bw.getPropertyDescriptors();
		for (PropertyDescriptor pd : pds) {
    
    
			// if  pd属性具有set方法 && 依赖检查中没有被忽略 && 没有被配置成 property 属性 && 不是简单类型
			if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
					!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
    
    
				// 添加到需要装配的集合中
				result.add(pd.getName());
			}
		}
		// 返回需要自动装配的bean集合
		return StringUtils.toStringArray(result);
	}

可以看到过滤条件

  1. 装配 属性具有set 方法: 因为后面的装配是通过set方法装配
  2. 依赖检查中没有被忽略
  3. 没有被property 属性,因为这里property 会被单独处理,不需要在这里保存
  4. 不是简单类型,即不属于Void、void、 Enum、CharSequence、Number、Date、Temporal、URI、URL、Locale、Class 和 八大基本数据类型及其包装类型。可以看到如下代码,ClassUtils.isPrimitiveOrWrapper(type) 判断是type是否属于基本数据类型或者其包装类型。
	public static boolean isSimpleValueType(Class<?> type) {
    
    
		return (Void.class != type && void.class != type &&
				(ClassUtils.isPrimitiveOrWrapper(type) ||
				Enum.class.isAssignableFrom(type) ||
				CharSequence.class.isAssignableFrom(type) ||
				Number.class.isAssignableFrom(type) ||
				Date.class.isAssignableFrom(type) ||
				Temporal.class.isAssignableFrom(type) ||
				URI.class == type ||
				URL.class == type ||
				Locale.class == type ||
				Class.class == type));
	}

3. 成员变量的注入

	for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
			if (pvsToUse == null) {
    
    
				if (filteredPds == null) {
    
    
					filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
				}
				pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
    
    
					return;
				}
			}
			pvs = pvsToUse;
		}
	}

这里通过 InstantiationAwareBeanPostProcessor 的 后处理器的postProcessPropertyValues 方法完成了属性的注入。Spring 默认是通过 AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues 的实现来完成的属性的注入。

@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    
    
		//
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
    
    
			// 在这里面又调用了 getBean 方法来获取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;
	}

这里不再具体分析 AutowiredAnnotationBeanPostProcessor 的实现(开衍生篇讲解,尚未成文),需要知道是 AutowiredAnnotationBeanPostProcessor 中完成了@Autowired、@Value 注解的自动注入功能。
大概逻辑是,获取被 @Autowired 修饰的 属性或者方法,如果是属性,则通过getBean 获取bean并注入,如果是方法,则获取方法参数后,invoke 方法(调用该方法,因为我们一般写的都是set方法,给属性注入赋值)。

4. applyPropertyValues

上面只是将属性保存了起来,并未真正设置到bean中,这里设置到bean中

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    
    
		if (pvs.isEmpty()) {
    
    
			return;
		}

		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
    
    
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;
		// 如果pvs 是 MutablePropertyValues 类型的封装
		if (pvs instanceof MutablePropertyValues) {
    
    
			mpvs = (MutablePropertyValues) pvs;
			// 如果 mpv 中的值类型已经转换完毕,则可以直接设置到BeanWrapper 中
			if (mpvs.isConverted()) {
    
    
				// Shortcut: use the pre-converted values as-is.
				try {
    
    
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
    
    
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			// 保存原始值,等待类型转换
			original = mpvs.getPropertyValueList();
		}
		else {
    
    
			// 保存原始值,等待类型转换
			original = Arrays.asList(pvs.getPropertyValues());
		}
		// 获取类型转换器
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
    
    
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		// 遍历属性,将属性转换为对应类的对应属性类型
		for (PropertyValue pv : original) {
    
    
			// 如果已经转换之后直接保存
			if (pv.isConverted()) {
    
    
				deepCopy.add(pv);
			}
			else {
    
    
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
    
    
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
    
    
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
    
    
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				if (resolvedValue == originalValue) {
    
    
					if (convertible) {
    
    
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
    
    
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
    
    
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
    
    
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
    
    
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
    
    
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

四、关于 自动装配的方式

在上面的代码中可以看到,自动装配分为两种情况,byName 和 byType。这里来一一介绍。

autowire 三种情况,如下。

	/**
	 * Constant that indicates no autowiring at all.
	 */
	NO(AutowireCapableBeanFactory.AUTOWIRE_NO),

	/**
	 * Constant that indicates autowiring bean properties by name.
	 */
	BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),

	/**
	 * Constant that indicates autowiring bean properties by type.
	 */
	BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);

可以通过 @Bean(autowire = Autowire.BY_NAME) 来指定注入方式。也可以通过xml配置中的 < bean ... autowire="byName"> 来指定,默认是 Autowire.NO,autowire 指的是当前bean内部引用的属性是以什么方式注入。。 不过需要注意的是,这个属性已经过时了,Spring并不推荐继续使用。
上面的代码看到了byName 和 byType 的属性装配过程。而 Autowire.NO 的处理过程则是通过 AutowiredAnnotationBeanPostProcessor.postProcessProperties 来解决的。

五、总结

populateBean 在bean创建结束之后,完成了对 bean属性的注入。根据byName、byType 的不同类型注入有不同的解析方式。

这一篇真难写,还没写清。


以上:内容部分参考
《Spring源码深度解析》
http://www.6tie.net/p/931985.html
https://www.jianshu.com/p/be3b96c48545
如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正

猜你喜欢

转载自blog.csdn.net/qq_36882793/article/details/106299180