Spring 5 AbstractAutowireCapableBeanFactory-- getTypeForFactoryMethod源码解析

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

AbstractAutowireCapableBeanFactory # resolveBeanClass

从工厂方法确定给定bean定义的目标类型,仅在尚未为目标bean注册单例实例时调用:

  1. 获取mbd的工厂方法返回类型【RootBeanDefinition#factoryMethodReturnType】,获取成功就返回出去
  2. 定一个通用返回类型【变量commonType】,用于存储 经过比较 AutowireUtils#resolveReturnTypeForFactoryMethod方法的返回结果 和Method#getReturnType方法的返回结果所得到共同父类。下面步骤都是为了获取commonType所实施的。
  3. 尝试获取bean的合并bean定义中的缓存用于自省的唯一工厂方法对象【RootBeanDefinition#factoryMethodToIntrospect】 【变量uniqueCandidate】,没成功获取到uniqueCandidate就通过下面步骤获取:
    1. 定义一个mbd指定的工厂类【变量factoryClass】
    2. 定义一个表明uniqueCandidate是否是静态方法的标记,默认是true【变量isStatic】
    3. 获取mbd的FactoryBean名【变量factoryBeanName】
      1. 如果获取成功,就意味着需要得到factoryBeanName所指的实例对象才能调用uniqueCandidate, 即uniqueCandidate不是静态方法:
        1. 如果factoryBeanName与beanName相等,会抛出BeanDefinitionStoreException,表明FactoryBean引用指向 相同的BeanDefinition
        2. 调用getType(factoryBeanName)获取其对应的类型【变量factoryClass】
        3. isStatic设置为false,表示uniqueCandidate不是静态方法
      2. 否则,调用resolveBeanClass(mbd, beanName, typesToMatch)来得到factoryClass
    4. 如果经过上面步骤,factoryClass还是没有成功获取就返回null,表示找到不明确的返回类型
    5. 如果mbd有配置构造函数参数值,就获取该构造函数参数值的数量,否则为0【变量 minNrOfArgs】
    6. 从该工厂的缓存候选工厂方法集合【factoryMethodCandidateCache】中获取候选方法,如果没有就调用 ReflectionUtils.getUniqueDeclaredMethods(factoryClass, ReflectionUtils.USER_DECLARED_METHODS))来 获取并添加到factoryMethodCandidateCache中【变量 candidates】
    7. 遍历candidates,元素为candidate.当candidate是否静态的判断结果与isStatic一致 且 candidate有资格作为工厂方法 且candidate的方法参数数量>=minNrOfArgs时:
      1. 如果candidate的参数数量>0:
        1. 获取candidate的参数类型数组【变量 paramTypes】
        2. 使用该工厂的参数名发现器【parameterNameDiscoverer】获取candidate的参数名 【变量 paramNames】
        3. 获取mbd的构造函数参数值 【变量 cav】
        4. 定义一个存储构造函数参数值ValueHolder对象的HashSet【变量 usedValueHolders】
        5. 定义一个用于存储参数值的数组【变量 args】
        6. 遍历args,索引为i:
          1. 获取第i个构造函数参数值ValueHolder对象【变量 valueHolder】,尽可能的提供位置,参数类型,参数名 以最精准的方式获取获取第i个构造函数参数值ValueHolder对象,传入usedValueHolder来提示cav#getArgumentValue方法 不应再次返回该usedValueHolder所出现的ValueHolder对象(如果有 多个类型的通用参数值,则允许返回下一个通用参数匹配项)
          2. 如果valueHolder获取失败,使用不匹配类型,不匹配参数名的方式获取除userValueHolders以外的 下一个参数值valueHolder对象
          3. 如果valueHolder获取成功,从valueHolder中获取值保存到args[i],然后将valueHolder添加到usedValueHolders缓存中, 表示该valueHolder已经使用过
        7. 调用AutowireUtils.resolveReturnTypeForFactoryMethod(candidate, args, getBeanClassLoader())获取 candidate的最终返回类型
        8. 如果commnType为null 且 returnType等于candidate直接获取的返回类型,uniqueCandidate就是candiate,否则为null
        9. 如果commonType为null就返回null,表示找到不明确的返回类型
        10. 捕捉获取commonType的所有异常,不再抛出任何异常,只打印出调试日志无法为工厂方法解析通用返回类型
      2. 如果candidate无需参数:
        1. 如果还没有找到commonType,candidate就为uniqueCandidate
        2. 获取candidate返回类型与commonType的共同父类,将该父类重新赋值给commonType
        3. 如果commonType为null就返回null,表示找到不明确的返回类型
    8. 缓存uniqueCandidate到mbd的factoryMethodToInstropect
    9. 如果commonType为null就返回null,表示找到不明确的返回类型。加上这个判断能保证下面的步骤commonType肯定有值
  4. 如果获取到了uniqueCandidate就获取uniqueCandidate的返回类型,否则就用commonType作为返回类型【变量cachedReturnType】
  5. 缓存cachedReturnType到mdb的factoryMethodReturnType
  6. 返回cachedReturnType封装的Class对象
/**
	 * Determine the target type for the given bean definition which is based on
	 * a factory method. Only called if there is no singleton instance registered
	 * for the target bean already.
	 * <p>工厂方法确定给定bean定义的目标类型。仅在尚未为目标bean注册单例实例时调用</p>
	 * <p>This implementation determines the type matching {@link #createBean}'s
	 * different creation strategies. As far as possible, we'll perform static
	 * type checking to avoid creation of the target bean.
	 * <p>此实现确定与createBean的不同创建策略匹配的类型。尽可能地,我们将执行静态类型
	 * 检查以避免创建目标bean</p>
	 * @param beanName the name of the bean (for error handling purposes)
	 *                 -- bean名(用于错误处理)
	 * @param mbd the merged bean definition for the bean
	 *            -- bean的合并bean定义
	 * @param typesToMatch the types to match in case of internal type matching purposes
	 * (also signals that the returned {@code Class} will never be exposed to application code)
	 *   -- 内部类型匹配时要匹配的类型(也表示返回的Class永远不会暴露给应用程序代码)
	 * @return the type for the bean if determinable, or {@code null} otherwise
	 * 		-- Bean类型(如果可以确定的话),否则为 null
	 * @see #createBean
	 */
	@Nullable
	protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    
    
		//尝试获取bean的合并bean定义中的缓存工厂方法返回类型
		ResolvableType cachedReturnType = mbd.factoryMethodReturnType;
		//如果成功获取到了bean的合并bean定义中的缓存工厂方法返回类型
		if (cachedReturnType != null) {
    
    
			//ResolvableType.resolve:将ResolvableType对象解析为Class,如果无法解析,则返回null
			return cachedReturnType.resolve();
		}
		//通用的返回类型,经过比较 AutowireUtils#resolveReturnTypeForFactoryMethod方法的返回结果
		// 和Method#getReturnType方法的返回结果所得到共同父类。
		Class<?> commonType = null;
		//尝试获取bean的合并bean定义中的缓存用于自省的唯一工厂方法对象
		Method uniqueCandidate = mbd.factoryMethodToIntrospect;
		//如果成功获取到了bean的合并bean定义中的缓存用于自省的唯一工厂方法对象
		if (uniqueCandidate == null) {
    
    
			Class<?> factoryClass;
			boolean isStatic = true;
			//获取bean的合并bean定义的工厂bean名
			String factoryBeanName = mbd.getFactoryBeanName();
			//如果成功获取到bean的合并bean定义的工厂bean名
			if (factoryBeanName != null) {
    
    
				//如果工厂bean名 与 生成该bean的bean名相等
				if (factoryBeanName.equals(beanName)) {
    
    
					//抛出 当BeanFactory遇到无效的bean定义时引发的异常 :
					//  工厂bean引用指向相同的bean定义
					throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
							"factory-bean reference points back to the same bean definition");
				}
				// Check declared factory method return type on factory class.
				// 检查工厂类上声明的工厂方法返回类型
				//获取factoryBeanName对应的工厂类
				factoryClass = getType(factoryBeanName);
				isStatic = false;
			}
			else {
    
    
				// Check declared factory method return type on bean class.
				// 检查bean类上声明的工厂方法返回类型
				//为mbd解析bean类,将bean类名解析为Class引用(如果需要),并将解析后的Class存储在
				// mbd中以备将来使用。
				factoryClass = resolveBeanClass(mbd, beanName, typesToMatch);
			}
			//如果mbd指定的工厂类获取失败
			if (factoryClass == null) {
    
    
				//返回null
				return null;
			}
			//如果factoryClass是CGLIB生成的子类,则返回factoryClass的父类,否则直接返回factoryClass
			factoryClass = ClassUtils.getUserClass(factoryClass);

			// If all factory methods have the same return type, return that type.
			// Can't clearly figure out exact method due to type converting / autowiring!
			// 如果所有工厂方法都具有相同的返回类型,则返回该类型。
			// 由于类型转换/自动装配,无法明确找出确切的方法。
			// 如果mbd有配置构造函数参数值,就获取该构造函数参数值的数量,否则为0
			int minNrOfArgs =
					(mbd.hasConstructorArgumentValues() ? mbd.getConstructorArgumentValues().getArgumentCount() : 0);
			//在子类和所有超类上获取一组唯一的已声明方法,即被重写非协变返回类型的方法
			// 首先包含子类方法和然后遍历父类层次结构任何方法,将过滤出所有与已包含的方法匹配的签名方法。
			Method[] candidates = this.factoryMethodCandidateCache.computeIfAbsent(factoryClass,
					clazz -> ReflectionUtils.getUniqueDeclaredMethods(clazz, ReflectionUtils.USER_DECLARED_METHODS));
			//遍历候选方法
			for (Method candidate : candidates) {
    
    
				//如果candidate是否静态的判断结果与isStatic一致 且 candidate有资格作为工厂方法 且 candidate的方法参数数量>=minNrOfArgs
				if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) &&
						candidate.getParameterCount() >= minNrOfArgs) {
    
    
					// Declared type variables to inspect?
					// 声明要检查的类型变量?
					// 如果candidate的参数数量>0
					if (candidate.getTypeParameters().length > 0) {
    
    
						try {
    
    
							// Fully resolve parameter names and argument values.
							// 完全解析参数名称和参数值
							// 获取candidate的参数类型数组
							Class<?>[] paramTypes = candidate.getParameterTypes();
							//参数名数组
							String[] paramNames = null;
							//获取参数名发现器
							ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
							//如果pnd不为null
							if (pnd != null) {
    
    
								//使用pnd获取candidate的参数名
								paramNames = pnd.getParameterNames(candidate);
							}
							//获取mbd的构造函数参数值
							ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
							// HashSet:HashSet简单的理解就是HashSet对象中不能存储相同的数据,存储数据时是无序的。
							// 但是HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。
							// 定义一个存储构造函数参数值ValueHolder对象的HashSet
							Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
							// 定义一个用于存储参数值的数组
							Object[] args = new Object[paramTypes.length];
							//遍历参数值
							for (int i = 0; i < args.length; i++) {
    
    
								//获取第i个构造函数参数值ValueHolder对象
								//尽可能的提供位置,参数类型,参数名以最精准的方式获取获取第i个构造函数参数值ValueHolder对象,传入
								// usedValueHolder来提示cav#getArgumentValue方法不应再次返回该usedValueHolder所出现的ValueHolder对象
								// (如果有 多个类型的通用参数值,则允许返回下一个通用参数匹配项)
								ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(
										i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders);
								//如果valueHolder获取失败
								if (valueHolder == null) {
    
    
									//使用不匹配类型,不匹配参数名的方式获取除userValueHolders以外的下一个参数值valueHolder对象
									valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders);
								}
								//如果valueHolder获取成功
								if (valueHolder != null) {
    
    
									//从valueHolder中获取值保存到第i个args元素中
									args[i] = valueHolder.getValue();
									//将valueHolder添加到usedValueHolders缓存中,表示该valueHolder已经使用过
									usedValueHolders.add(valueHolder);
								}
							}
							//获取candidate的最终返回类型,该方法支持泛型情况下的目标类型获取
							Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(
									candidate, args, getBeanClassLoader());
							//如果commnType为null 且 returnType等于candidate直接获取的返回类型,唯一候选方法就是candiate,否则为null
							uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ?
									candidate : null);
							//获取returnType与commonType的共同父类,将该父类重新赋值给commonType
							commonType = ClassUtils.determineCommonAncestor(returnType, commonType);
							//如果commonType为null
							if (commonType == null) {
    
    
								// Ambiguous return types found: return null to indicate "not determinable".
								// 找到不明确的返回类型:返回null表示'不可确定'
								return null;
							}
						}
						//捕捉获取commonType的所有异常
						catch (Throwable ex) {
    
    
							if (logger.isDebugEnabled()) {
    
    
								//无法为工厂方法解析通用返回类型
								logger.debug("Failed to resolve generic return type for factory method: " + ex);
							}
						}
					}
					//如果candidate无需参数
					else {
    
    
						//如果还没有找到commonType,candidate就为唯一的候选方法
						uniqueCandidate = (commonType == null ? candidate : null);
						//获取candidate返回类型与commonType的共同父类,将该父类重新赋值给commonType
						commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType);
						//如果commonType为null
						if (commonType == null) {
    
    
							// Ambiguous return types found: return null to indicate "not determinable".
							// 找到不明确的返回类型:返回null表示'不可确定'
							return null;
						}
					}
				}
			}
			//缓存uniqueCandidate到mbd的factoryMethodToInstropect
			mbd.factoryMethodToIntrospect = uniqueCandidate;
			//如果commonType为null,加上这个判断能保证下面的步骤commonType肯定有值
			if (commonType == null) {
    
    
				// 找到不明确的返回类型:返回null表示'不可确定'
				return null;
			}
		}

		// Common return type found: all factory methods return same type. For a non-parameterized
		// unique candidate, cache the full type declaration context of the target factory method.
		// 找到常见的返回类型:所有工厂方法都返回相同的类型。对象非参数化的唯一候选者,缓存目标工厂方法的
		// 完整类型声明上下文
		//如果获取到了uniqueCandidate就获取uniqueCandidate的返回类型,否则就用commonType作为返回类型
		cachedReturnType = (uniqueCandidate != null ?
				ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType));
		//缓存cachedReturnType到mdb的factoryMethodReturnType
		mbd.factoryMethodReturnType = cachedReturnType;
		//返回cachedReturnType封装的Class对象
		return cachedReturnType.resolve();
	}

getType(factoryBeanName);

确定具有给定名称的bean类型(为了确定其对象类型,默认让FactoryBean以初始化)。

Spring 5 AbstractBeanFactory-- getType源码解析

resolveBeanClass(mbd, beanName, typesToMatch);

为mdb解析出对应的bean class

Spring 5 AbstractBeanFactory – resolveBeanClass源码解析

ClassUtils.getUserClass(factoryClass);

如果clazz是CGLIB生成的子类,则返回该子类的父类,否则直接返回要检查的类

/**
	 * Return the user-defined class for the given class: usually simply the given
	 * class, but the original class in case of a CGLIB-generated subclass.
	 * <p>
	 *     返回给定实例的用户定义类:通常给定的实例是简单的类,但是在一个CGLIB生成的子类
	 * 	   情况下,则是原始类
	 * </p>
	 * @param clazz the class to check 检查类
	 * @return the user-defined class 用户定义的
	 */
	public static Class<?> getUserClass(Class<?> clazz) {
    
    
		//如果clazz的全类名包含'$$'字符串,表示它有可能是GGLIB生成的子类
		if (clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
    
    
			//获取clazz的父类
			Class<?> superclass = clazz.getSuperclass();
			//如果superclass不为null 且 superclass不是Object
			if (superclass != null && superclass != Object.class) {
    
    
				//直接返回父类
				return superclass;
			}
		}
		//直接返回检查类
		return clazz;
	}

ReflectionUtils.getUniqueDeclaredMethods(clazz, ReflectionUtils.USER_DECLARED_METHODS)

Spring 5 ReflectionUtils 源码注释

getParameterNameDiscoverer()


/**
	 * Resolver strategy for method parameter names.
	 * <p>方法参数的解析策略</p>
	 * */
	@Nullable
	private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();


/**
	 * Return the ParameterNameDiscoverer to use for resolving method parameter
	 * names if needed.
	 * <p>如果需要,返回ParameterNameDiscover来解析方法参数名称</p>
	 */
	@Nullable
	protected ParameterNameDiscoverer getParameterNameDiscoverer() {
    
    
		return this.parameterNameDiscoverer;
	}

Spring 5 ParameterNameDiscoverer 源码注释

ClassUtils.determineCommonAncestor(returnType, commonType);

Spring 5 ClassUtils 源码注释

ResolvableType.forMethodReturnType(uniqueCandidate)

Spring 5 ResolvableType 源码注释

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108347133