首页 > 编程语言 >Spring源码-AbstractAutowireCapableBeanFactory的autowireConstructor

Spring源码-AbstractAutowireCapableBeanFactory的autowireConstructor

时间:2022-09-30 22:11:55浏览次数:47  
标签:constructorToUse mbd Spring beanName 源码 argsToUse AbstractAutowireCapableBeanFac

autowireConstructor:

  protected BeanWrapper autowireConstructor(
		String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

ConstructorResolver的autowireConstructor:

	public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
		@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

	BeanWrapperImpl bw = new BeanWrapperImpl();
	this.beanFactory.initBeanWrapper(bw);

	Constructor<?> constructorToUse = null; // 使用的构造函数
	ArgumentsHolder argsHolderToUse = null; // 使用的参数封装
	Object[] argsToUse = null; // 构造参数

	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	else {
		Object[] argsToResolve = null;
		synchronized (mbd.constructorArgumentLock) {
			constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; // 获取BeanDefinition中解析完成的构造函数
			if (constructorToUse != null && mbd.constructorArgumentsResolved) {
				// 从缓存中找到了构造器,那么继续从缓存中寻找缓存的构造器参数
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					argsToResolve = mbd.preparedConstructorArguments; // 没有缓存的参数,就需要获取配置文件中配置的参数
				}
			}
		}
		// 如果缓存中没有缓存的参数的话,即argsToResolve不为空,就需要解析配置的参数
		if (argsToResolve != null) {
			// 解析参数类型,比如将配置的String类型转换为list、boolean等类型
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
		}
	}

	if (constructorToUse == null || argsToUse == null) {
		// Take specified constructors, if any.
		Constructor<?>[] candidates = chosenCtors;
		if (candidates == null) {
			// 如果candidates为null,则获取bean的Class对象,在获取所有的构造函数
			Class<?> beanClass = mbd.getBeanClass();
			try {
				candidates = (mbd.isNonPublicAccessAllowed() ?
						beanClass.getDeclaredConstructors() : beanClass.getConstructors());
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Resolution of declared constructors on bean Class [" + beanClass.getName() +
						"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
			}
		}
		// 如果candidates只有一个元素 且 没有传入构造函数值 且 mbd也没有构造函数参数值则调用唯一的构造函数并放到缓存中。
		if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
			Constructor<?> uniqueCandidate = candidates[0];
			if (uniqueCandidate.getParameterCount() == 0) {
				synchronized (mbd.constructorArgumentLock) {
					mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
					mbd.constructorArgumentsResolved = true;
					mbd.resolvedConstructorArguments = EMPTY_ARGS;
				}
				bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
				return bw;
			}
		}

		// Need to resolve the constructor.
		boolean autowiring = (chosenCtors != null ||
				mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		ConstructorArgumentValues resolvedValues = null;
		// 获取构造函数的最小参数个数
		int minNrOfArgs;
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
			ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
			resolvedValues = new ConstructorArgumentValues();
			minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
		}
		// 对候选构造函数排序
		AutowireUtils.sortConstructors(candidates);
		int minTypeDiffWeight = Integer.MAX_VALUE;
		Set<Constructor<?>> ambiguousConstructors = null;
		Deque<UnsatisfiedDependencyException> causes = null;

		// 以下的循环遍历所有的候选构造函数,通过参数个数,参数的类型计算构造函数的typeDiffWeight值,选取typeDiffWeight最小的最为最优构造函数
		for (Constructor<?> candidate : candidates) {
			int parameterCount = candidate.getParameterCount();

			if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
				// Already found greedy constructor that can be satisfied ->
				// do not look any further, there are only less greedy constructors left.
				break;
			}
			if (parameterCount < minNrOfArgs) {
				continue;
			}

			ArgumentsHolder argsHolder;
			Class<?>[] paramTypes = candidate.getParameterTypes();
			if (resolvedValues != null) {
				try {
					String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
					if (paramNames == null) {
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); // 获取参数名称探索器
						if (pnd != null) {
							paramNames = pnd.getParameterNames(candidate); // 获取指定构造函数的参数名称
						}
					}
					// 根据名称和数据类型创建argsHolder
					argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
							getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
				}
				catch (UnsatisfiedDependencyException ex) {
					if (logger.isTraceEnabled()) {
						logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
					}
					// Swallow and try next constructor.
					if (causes == null) {
						causes = new ArrayDeque<>(1);
					}
					causes.add(ex);
					continue;
				}
			}
			else {
				// Explicit arguments given -> arguments length must match exactly.
				if (parameterCount != explicitArgs.length) {
					continue;
				}
				argsHolder = new ArgumentsHolder(explicitArgs);
			}

			int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
					argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
			// Choose this constructor if it represents the closest match.
			if (typeDiffWeight < minTypeDiffWeight) {
				constructorToUse = candidate;
				argsHolderToUse = argsHolder;
				argsToUse = argsHolder.arguments;
				minTypeDiffWeight = typeDiffWeight;
				ambiguousConstructors = null;
			}
			else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
				if (ambiguousConstructors == null) {
					ambiguousConstructors = new LinkedHashSet<>();
					ambiguousConstructors.add(constructorToUse);
				}
				ambiguousConstructors.add(candidate);
			}
		}

		//以下两种情况会抛异常
		// 1、没有确定使用的构造函数
		// 2、存在模糊的构造函数并且不允许存在模糊的构造函数
		if (constructorToUse == null) {
			if (causes != null) {
				UnsatisfiedDependencyException ex = causes.removeLast();
				for (Exception cause : causes) {
					this.beanFactory.onSuppressedException(cause);
				}
				throw ex;
			}
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Could not resolve matching constructor " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
		}
		else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Ambiguous constructor matches found in bean '" + beanName + "' " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
					ambiguousConstructors);
		}

		if (explicitArgs == null && argsHolderToUse != null) {
			argsHolderToUse.storeCache(mbd, constructorToUse); // 将解析的构造函数加入缓存
		}
	}

	Assert.state(argsToUse != null, "Unresolved constructor arguments");
	bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); // 通过构造函数实例化bean并加入BeanWrapper中
	return bw;
}

instantiate:

private Object instantiate(
		String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {

	try {
		InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
		if (System.getSecurityManager() != null) {
			return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
					this.beanFactory.getAccessControlContext());
		}
		else {
			return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean instantiation via constructor failed", ex);
	}
}

根据实例化策略实例化bean。

	@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
		final Constructor<?> ctor, Object... args) {

	if (!bd.hasMethodOverrides()) {
		if (System.getSecurityManager() != null) {
			// use own privileged to change accessibility (when security is on)
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(ctor);
				return null;
			});
		}
		return BeanUtils.instantiateClass(ctor, args);
	}
	else {
		return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
	}
}

如果没有MethodOverrides,即没有lookup-method和replaced-method标签,则调用构造函数反射实例化bean,否则生成cglib代理处理lookup-method和replaced-method标签

标签:constructorToUse,mbd,Spring,beanName,源码,argsToUse,AbstractAutowireCapableBeanFac
From: https://www.cnblogs.com/shigongp/p/16746217.html

相关文章