spring bean生命周期三---Spring Bean populateBean 属性填充阶段

目录

 

前言

一、populateBean - 概述

二、populateBean - 详解

2.1. 属性填充判断 

2.2、自动装配 :autowiring自动装配的

2.2.1、自动装配 - autowireByName

2.2.2、 自动装配 - autowireByType

2.3、排除规则 - unsatisfiedNonSimpleProperties

3、@Autowired 和 @Resource 的注入工作

3.1、第六次调用后置处理器  InstantiationAwareBeanPostProcessor#postProcessProperties

3.2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues

3.3、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues

3.4、需要依赖注入的对象 DefaultListableBeanFactory#resolveDependency 

4. applyPropertyValues

三、总结


前言

本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。

我们在上一篇文章:spring bean生命周期二---Spring Bean实例化( Instantiation)阶段 中完成了bean的实例化过程 ,但是属性内容还没有注入,本文就是将bean的属性进行注入的过程

一、populateBean - 概述

我们这里先整体过一遍代码,后面进行每一步的详细解读。

// AbstractAutowireCapableBeanFactory#populateBean
	// beanName : bean 的name
	// mbd  :  bean的定义信息
	// bw  : bean实例的包装类型,里面有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.
		//
		boolean continueWithPropertyPopulation = true;
         //mbd.isSynthetic() 合成类
		//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
		// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}
		//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
		//这个是程序员在 bd中 写入的属性rootBeanDefinition.getPropertyValues().add("type","男的");
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		 2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {


			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			//根据Bean名称进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			//根据Bean类型进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//对非autowiring的属性进行依赖注入处理
		// 后处理器已经初始化
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				//TODO 获取的bean所有后置处理器找到 所有需要注入的属性
				// 这里会进行 @Autowired 和 @Resource 的注入工作
				// 属性填充InstantiationAwareBeanPostProcessor
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//下面是完成属性注入的
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				// 依赖检查,对应 depends-on 属性,3.0 已弃用
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		if (pvs != null) {
			 4. 将属性应用到bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

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

  1. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法,可以决定程序是否继续进行属性填充。只要有一个 InstantiationAwareBeanPostProcessor 返回false,都会终止属性填充的过程。这个过程属于实例化 后置阶段上上文已经描述过了
  2. 自动装配 :autowiring自动装配的。根据注入类型(name或type),提取依赖的bean,并统一存入到 propertyValues 中。
  3. @Autowired 和 @Resource 的属性注入工作,调用后置处理器应用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法,对属性获取完毕填充前对属性的再次处理。

         有两个实现类型 :1、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的

                                        2、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的

  1. 将所有 propertyValues 中的属性填充至 BeanWrapper 中。

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

  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation : 是否使用 InstantiationAwareBeanPostProcessor进行属性装配
  • InstantiationAwareBeanPostProcessor.postProcessProperties : 进行属性装配

二、populateBean - 详解

2.1. 属性填充判断 

这个的上文中已经描述过了这里就简单贴出代码

 //mbd.isSynthetic() 合成类
		//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
		// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

如下,这里调用了InstantiationAwareBeanPostProcessor #postProcessAfterInstantiation 方法来决定是否继续注入属性。该方法正常返回true。如果返回false 则将取消对此bean调用任何后续的InstantiationAwareBeanPostProcessor 方法。

2.2、自动装配 :autowiring自动装配的

在下面这段代码中,对 autowiring自动装配中根据名称或类型自动注入的种类进行自动装配。


    		 2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {


			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			//根据Bean名称进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			//根据Bean类型进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}

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

2.2.1、自动装配 - autowireByName

//根据名称对属性进行自动依赖注入
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符串,URL等都是简单属性)进行处理
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			//如果Spring IOC容器中包含指定名称的Bean
			if (containsBean(propertyName)) {
				//调用getBean方法向IOC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
				Object bean = getBean(propertyName);
				//为指定名称的属性赋予属性值
				pvs.add(propertyName, bean);
				//指定名称属性注册依赖Bean名称,进行属性依赖注入
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("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进行注入。 关于 unsatisfiedNonSimpleProperties 方法在后面有讲解。

2.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 autowiredBeanNames = new LinkedHashSet<>(4);
		//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符
		//URL等都是简单属性)进行处理
		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.
				//不对Object类型的属性进行autowiring自动依赖注入
				if (Object.class != pd.getPropertyType()) {
					//获取属性的setter方法
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					//检查指定类型是否可以被转换为目标对象的类型
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
					//创建一个要被注入的依赖描述
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					//根据容器的Bean定义解析依赖关系,返回所有要被注入的Bean对象
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						//为属性赋值所引用的对象
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						//指定名称属性注册依赖Bean名称,进行属性依赖注入
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isDebugEnabled()) {
							logger.debug("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. 关于 registerDependentBean 方法,我们在之前的文章中有过解释,详阅 Spring 源码分析三 :bean的加载① - doGetBean概述

  2. 这里面的主要的逻辑被封装到了DefaultListableBeanFactory#resolveDependency 方法的具体实现我们在后继查看。目前我所知另外调用地方:

    1. AutowiredAnnotationBeanPostProcessor#postProcessProperties  中注入处理 @Autowired 注入的时候也调用了该方法
    2. ConstructorResolver#autowireConstructor 在 resolveAutowiredArgument( methodParam, beanName, autowiredBeanNames, converter, fallback); 时也调用了该方法。

2.3、排除规则 - unsatisfiedNonSimpleProperties

autowireByName 和 autowireByType方法中,都有如下一行代码

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

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

protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
		Set 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. 依赖检查中没有被忽略isExcludedFromDependencyCheck(pd) 
  3. 没有被property 属性,因为这里property 会被单独处理,不需要在这里保存
  4. 不是简单类型,即不属于Void、void、 Enum、CharSequence、Number、Date、Temporal、URI、URL、Locale、Class 和 八大基本数据类型及其包装类型。

3、@Autowired 和 @Resource 的注入工作

这里只要时候  InstantiationAwareBeanPostProcessor#postProcessProperties 后置处理器处理

PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				//TODO 获取的bean所有后置处理器找到 所有需要注入的属性
				// 这里会进行 @Autowired 和 @Resource 的注入工作
				// 属性填充InstantiationAwareBeanPostProcessor
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//下面是完成属性注入的
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
						if (pvs == null) {
							return;
						}
					}
				}
			}

3.1、第六次调用后置处理器  InstantiationAwareBeanPostProcessor#postProcessProperties

这里通过 InstantiationAwareBeanPostProcessor #postProcessPropertyValues 方法完成了属性的注入。

1、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues中的实现类 处理 @Autowired 注解和@Value 注解的自动注入功能。

 2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues中的实现类 处理  @Resource注解、@PostConstruct等通用注解。

3.2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues

//处理属性值
	@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		//获取@Resource注解中配置的属性值元数据
		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
		}
		return pvs;
	}

获取@Resource注解中配置的属性值元数据

这里主要是对 @Resource 进行注入findResourceMetadata在MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition的时候执行过.

所以这里, 大概率是从缓存中拿取结果, 然后进行注入操作. 事实上, 也确实如此.

/获取@Resource注解中配置的属性值元数据
	private InjectionMetadata findResourceMetadata(String beanName, final Class clazz, @Nullable PropertyValues pvs) {
		// Fall back to class name as cache key, for backwards compatibility with custom callers.
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		// Quick check on the concurrent map first, with minimal locking.
		//首先从容器缓存中查找
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
			synchronized (this.injectionMetadataCache) {
				metadata = this.injectionMetadataCache.get(cacheKey);
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
					if (metadata != null) {
						metadata.clear(pvs);
					}
					metadata = buildResourceMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

metadata.inject(bean, beanName, pvs);

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		//
		Collection checkedElements = this.checkedElements;
		Collection 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);
			}
		}
	}

 

 

element.inject(target, beanName, pvs);的实现类有三个

这里最终会调用本类中的方法:

org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject 方法

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();
				}
			}
		}

3.3、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues

大概逻辑是,获取被 @Autowired 修饰的 属性或者方法,如果是属性,则通过getBean 获取bean并注入如果是方法,则获取方法参数后,invoke 方法(调用该方法,因为我们一般写的都是set方法,给属性注入赋值)。

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

		//获取指定类中autowire相关注解的元信息
		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;
	}

这里主要是对 @Autowired 和 @Value 进行注入的. InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);

findAutowiringMetadata在MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition的时候执行过.

所以此处, 是从缓存中拿取结果, 然后进行注入操作.

最终会调用本类中的方法:

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject

//对字段进行注入
		@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			//获取注入元素对象
			Field field = (Field) this.member;
			Object value;
			//如果当前对象在容器中被缓存 默认为false.
			if (this.cached) {
				//根据Bean名称解析缓存中的字段值
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			//如果当前对象没有被容器缓存
			else {
				//创建一个字段依赖描述符
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set autowiredBeanNames = new LinkedHashSet<>(1);
				Assert.state(beanFactory != null, "No BeanFactory available");
				//获取容器中的类型转换器
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {
					//根据容器中Bean定义,解析指定的依赖关系,获取需要依赖注入的对象
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				//线程同步,确保容器中数据一致性
				synchronized (this) {
					//如果当前对象没有被容器缓存
					if (!this.cached) {
						//获取到了当前对象的依赖对象,并且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);
				//TODO 为Bean对象的字段设置值 完成了属性填充
				field.set(bean, value);
			}
		}
	}

3.4、需要依赖注入的对象 DefaultListableBeanFactory#resolveDependency 

根据容器中Bean定义,解析指定的依赖关系,获取需要依赖注入的对象。这里是很重要的方法在很多地方都使用到

 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency

	@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set 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 {
			//ToDO 这个一般为空 这个是特殊情况 处理bean是否懒加载,如果懒加载,创建一个代理对象注入bean
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				// 下面是正常情况
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

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

DefaultListableBeanFactory#doResolveDependency

	@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set 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注解中的value属性中的值,这里取出的值是未经修改的值,即带有 ${} 标签的值。如果descriptor未被@Value标注,则返回null
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				// 到这里说明属性被 @Value 注解修饰了,这里是解析 @Value 注解的逻辑
				// 如果value不为nul
				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);
				}
				// 类型转换,把解析出来的结果转成type类型
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}

			//TODO 对集合类型进行处理,包括,Array、Collection、Map。后面详解
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				// 如果解析出来集合类型,则直接返回
				return multipleBeans;
			}

			//调用查找所有类型为type的实例,存放在matchingBeans 
			//  (在 resolveMultipleBeans 方法中也是核心也是调用该方法)。下面详解
			Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			//TODO 这个是处理 这个是根据 类型找到多个bean(也就是实现类有多个)
			// 如果有多个bean 则在按照名字来匹配多个bean 找出来一个bean 用来注入
			if (matchingBeans.size() > 1) {
				// 按以下顺序,找到符合条件的就直接返回
				// 1. 挑选出被标识为primary的bean
				// 2. 挑选标识了@Priority,且先级级最高的bean。可以不标识,一旦标识,不允许同一优先级的存在
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						// 非集合类,找到了多个符合条件的Bean,抛出异常
						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;
					}
				}
				//根据名字从 根据类型的获得的matchingBeans 找到bean
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				// 如果只找到了唯一匹配的元素,则直接使用
				Map.Entry entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				// 将待装配的Bean名称放入autowiredBeanNames集合里
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
				// 这里又去调用 getBean 方法去获取bean
				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);
		}
	}

DefaultListableBeanFactory#resolveMultipleBeans

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

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

		final Class type = descriptor.getDependencyType();
		// 如果是 StreamDependencyDescriptor 类型,则返回流的形式
		if (descriptor instanceof StreamDependencyDescriptor) {
			Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			Stream 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 matchingBeans = findAutowireCandidates(beanName, componentType,
					new MultiElementDescriptor(descriptor));
			// 如果是未找到匹配的bean,则返回null,
			if (matchingBeans.isEmpty()) {
				return null;
			}
			// 保存所有适配的 beanName
			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 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 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 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 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 方法。

DefaultListableBeanFactory#findAutowireCandidates

	protected Map findAutowireCandidates(
			@Nullable String beanName, Class requiredType, DependencyDescriptor descriptor) {
		// 根据 Class 类型,找到对应的候选beanName,
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map result = new LinkedHashMap<>(candidateNames.length);
		// 这里我们一般不会涉及。如果注入的是 resolvableDependencies key类型,则会装配成value类型
		for (Map.Entry, 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);
			}
		}
		// 如果目前找到的匹配的bean集合为空
		if (result.isEmpty()) {
			// Array || Collection || Map 。即是否表示多个bean的集合类型
			boolean multiple = indicatesMultipleBeans(requiredType);
			// Consider fallback matches if the first pass failed to find anything...
			DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
			for (String candidate : candidateNames) {
				// 非自引用 && 允许被注入 && (非集合类 || 解析 @Qualifier 注解或者 javax.inject.Qualifier类成功)
				// 这里开始分析解析的属性是否被 @Qualifier 注解或者 javax.inject.Qualifier类 限定符限定了
				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 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));
		}
	}

这里提两点:

  1. 这里需要注意 resolvableDependencies。其在 DefaultListableBeanFactory#resolvableDependencies 定义如下,其作用是,当一些其他的类需要装配key类型的bean时,实际装配的类型是key对应的value 类型。

    	/** Map from dependency type to corresponding autowired value. */
    	// key 是映射值,value是实际注入值
    	private final Map, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
    

    在 Spring默认的代码中,仅仅有八个元素保存到其中,如下:

spring bean生命周期三---Spring Bean populateBean 属性填充阶段_第1张图片

  1. 从上面的代码可以看到,Spring寻找合适的bean的要求是一再放宽的 : 非自引用 -> 被 Qualifier 限定符修饰的bean -> 自引用。

  2. autowire-candidate :xml中在注入bean 的时候有该属性。@Bean也有对应的属性。其作用是用来标记当前bean是否会被作为注入的候选bean。默认值 true:表示其他bean可以把当前bean作为属性注入。如果false:表示其他bean选在注入属性 bean时将忽略当前bean。这一点在上面的代码中也有体现。

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 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 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);
		}
	}

三、总结

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

你可能感兴趣的:(spring源码学习)