ConstructorResolver
文章目录
- 源码解析
- instantiateUsingFactoryMethod方法
- autowireConstructor 方法
源码解析
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Bean的实例化阶段,会将Bean的实例对象封装成BeanWrapperImpl包装对象
BeanWrapper instanceWrapper = null;
// 如果是单例模式,则先尝试从factoryBeanInstanceCache缓存中获取实例对象,并从缓存中移除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 若缓存中没有可用的BeanWrapper,则调用createBeanInstance方法创建Bean实例,将BeanDefinition转换为BeanWrapper对象。
// 使用合适的实例化策略来创建 Bean 的实例:工厂方法、构造函数自动注入、简单初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// ...
createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法,创建一个 Bean 的实例对象,如下:
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 从 Bean 定义中解析出 Bean 的 Class 对象。
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// ...
// 如果配置了 factory-method 工厂方法,则调用该方法来创建一个实例对象
// 通过 @Bean 标注的方法会通过这里进行创建
if (mbd.getFactoryMethodName() != null) {
// 这个过程非常复杂,你可以理解为:
// 找到最匹配的 Method 工厂方法,获取相关参数(依赖注入),然后通过调用该方法返回一个实例对象(反射机制)
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// ...
}
instantiateUsingFactoryMethod方法
通过factoryMethodName
工厂方法创建一个实例对象,例如 XML 配置的factory-method
属性或者@Bean
标注的方法都会解析成factoryMethodName
属性。
这个过程非常复杂,你可以理解为去找到最匹配的Method
工厂方法,获取相关入参(依赖注入),然后调用该方法返回一个实例对象(反射机制),方法如下:
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
创建ConstructorResolver
对象,然后调用其instantiateUsingFactoryMethod(...)
方法,如下:
class ConstructorResolver {
// ConstructorResolver.java
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 构造 BeanWrapperImpl 对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 BeanWrapperImpl,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
this.beanFactory.initBeanWrapper(bw);
// -------------------------获取工厂方法的相关信息-------------------------
// <1> 获取工厂方法的相关信息
// 工厂方法所在类对应的 Bean(静态方法不会有)
Object factoryBean;
// 工厂方法所在类的 Class 对象
Class<?> factoryClass;
// 是否为 static 修饰的静态方法
boolean isStatic;
// 获取工厂方法所在类对应的 Bean 的名称(静态方法不会有)
String factoryBeanName = mbd.getFactoryBeanName();
// 非静态方法
if (factoryBeanName != null) {
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
// 获取工厂方法所在类对应的 Bean,不然无法调用工厂方法
factoryBean = this.beanFactory.getBean(factoryBeanName);
// 如果是单例模式,已经存在对应的 Bean,则抛出重复创建的异常
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
factoryClass = factoryBean.getClass();
isStatic = false;
}
// 静态方法
else {
// 静态方法没有找到对应的 Class 对象无法被调用,则抛出异常
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
// -------------------------尝试获取工厂方法对象和入参-------------------------
// 尝试获取工厂方法对象和参数
// 工厂方法对象
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 方法参数
Object[] argsToUse = null;
// 如果方法入参指定了参数,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 否则,尝试从 RootBeanDefinition 中获取已解析出来的工厂方法和入参
else {
Object[] argsToResolve = null;
// 因为可能前面解析了,会临时缓存,避免再次解析
synchronized (mbd.constructorArgumentLock) { // 加锁
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
// 如果工厂方法被解析了,那么参数也可能解析过
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 没有解析过的参数,则尝试从 RootBeanDefinition 中获取未被解析过的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果获取到了未被解析过的入参,则进行解析
if (argsToResolve != null) {
// 处理参数值,类型转换,例如给定方法 A(int, int),配置了 A("1"、"2") 两个参数,则会转换为 A(1, 1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
// -------------------------找到所有匹配的工厂方法-------------------------
// 如果上一步没有找到工厂方法对象或方法入参集合,则需要进行接下来的解析过程,首先找到所有匹配的工厂方法
if (factoryMethodToUse == null || argsToUse == null) {
// 获取工厂方法所在的类的实例 Class 对象,因为可能是 Cglib 提升过的子类
factoryClass = ClassUtils.getUserClass(factoryClass);
// 获取工厂方法所在的类中所有方法对象
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
// 找到这个类中匹配的工厂方法
List<Method> candidateList = new ArrayList<>();
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic // 是否和 `isStatic` 匹配
&& mbd.isFactoryMethod(candidate)) { // 和定义的工厂方法的名称是否相等
candidateList.add(candidate);
}
}
// 如果只有一个匹配的方法,且这个方法没有给指定的入参,且本身也没有定义参数,且这个方法没有定义入参
// 则直接调用这个方法创建一个实例对象(反射机制),并返回
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// -------------------------开始找最匹配的工厂方法-------------------------
// 开始找最匹配的工厂方法
// 将匹配的工厂方法转换成数组
Method[] candidates = candidateList.toArray(new Method[0]);
// 将匹配的方法进行排序,public 方法优先,入参个数多的优先
AutowireUtils.sortFactoryMethods(candidates);
// 用于承载解析后的方法参数值
ConstructorArgumentValues resolvedValues = null;
// 是否是构造器注入
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
// 匹配方法的集合
Set<Method> ambiguousFactoryMethods = null;
// -------------------------确定方法参数的入参数量-------------------------
// 确定方法参数的入参数量,匹配的方法的入参数量要多余它
// 方法的参数数量的最小值
int minNrOfArgs;
// 如果当前方法指定了入参,则使用其个数作为最小值
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
// 否则,从 RootBeanDefinition 解析出方法的参数个数作为最小值
else {
// RootBeanDefinition 定义了参数值
if (mbd.hasConstructorArgumentValues()) {
// 方法的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析定义的参数值,放入 `resolvedValues` 中,并返回参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {
minNrOfArgs = 0;
}
}
// 记录 UnsatisfiedDependencyException 异常的集合
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历匹配的方法
for (Method candidate : candidates) {
// 方法体的参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
// -------------------------解析出工厂方法的入参-------------------------
// 解析出工厂方法的入参
// 保存参数的对象
ArgumentsHolder argsHolder;
// 如果当前方法指定了入参,则直接使用
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
// 显示给定参数,参数长度必须完全匹配
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 根据参数创建参数持有者 ArgumentsHolder 对象
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 否则,通过依赖注入获取入参
else {
// 为提供参数,解析构造参数
try {
String[] paramNames = null;
// 获取 ParameterNameDiscoverer 参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
// 获取方法的参数名称
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
// 解析出方法的入参,参数值会被依赖注入
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
// 若发生 UnsatisfiedDependencyException 异常,添加到 causes 中。
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// -------------------------根据权重获取最匹配的方法-------------------------
// 因为会遍历所有匹配的方法,所以需要进行权重的判断,拿到最优先的那个
// 判断解析构造函数的时候是否以宽松模式还是严格模式,默认为 true
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 代表最匹配的结果,则选择作为符合条件的方法
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// 如果具有相同参数数量的方法具有相同的类型差异权重,则收集此类型选项
// 但是,仅在非宽松构造函数解析模式下执行该检查,并显式忽略重写方法(具有相同的参数签名)
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
// 查找到多个可匹配的方法
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
// 没有找到对应的工厂方法,则抛出异常
if (factoryMethodToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
// 将解析出来的工厂方法和入参缓存,设置到 RootBeanDefinition 中,因为整个过程比较复杂,避免再次解析
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
Assert.state(argsToUse != null, "Unresolved factory method arguments");
// 调用工厂方法创建一个实例对象(反射机制),并设置到 `bw` 中
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
}
上面整个过程非常复杂,这里进行简单概括:
- 找到对应的工厂方法,如果是非静态方法,则需要先依赖查找到所在类对应的 Bean,因为需要根据这个 Bean
- 去调用对应的工厂方法,而静态方法不用,可以根据其 Class 对象调用对应的工厂方法 如果工厂方法有入参,则需要注入相关对象(依赖注入)
- 调用这个方法(反射机制),返回一个实例对象
autowireConstructor 方法
这个过程和上一个方法一样非常复杂,不过差不太多,你可以理解为去找到当前 Bean 的构造方法,获取相关入参(构造器注入),然后调用该构造方法返回一个实例对象(反射机制),方法如下:
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
创建ConstructorResolver
对象,然后调用其autowireConstructor(...)
方法,如下:
// ConstructorResolver.java
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 构造 BeanWrapperImpl 对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 BeanWrapperImpl,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
this.beanFactory.initBeanWrapper(bw);
// -------------------------尝试获取构造方法和入参-------------------------
// <1> 尝试获取构造方法和入参
// 构造方法
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 构造方法的入参集合
Object[] argsToUse = null;
// <1.1> 如果当前方法入参指定了参数,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// <1.2> 否则,尝试从 RootBeanDefinition 中获取已解析出来的构造方法和入参
else {
// 因为可能前面解析了,会临时缓存,避免再次解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 如果构造方法被解析了,那么参数也可能解析过
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 没有解析过的参数,则尝试从 RootBeanDefinition(合并后)中获取未被解析过的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果获取到了未被解析过的入参
if (argsToResolve != null) {
// 处理参数值,类型转换,例如给定方法 A(int, int),配配置了 A("1"、"2") 两个参数,则会转换为 A(1, 1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// -------------------------开始获取构造方法和入参-------------------------
// <2> 如果上一步没有找到构造方法或入参集合,找到所有匹配的工厂方法,首先找到所有匹配的构造方法
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// <2.1> 获取所有的构造方法,如果当前方法指定了构造方法的集合,则使用这个集合
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
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);
}
}
// <2.2> 如果构造方法只有一个,且当前方法的入参没有指定参数,且本身也没有定义参数,且这个构造方法没有定义入参
// 则直接调用这个构造方法创建一个实例对象(反射机制),并返回
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;
// -------------------------确定构造方法的入参数量-------------------------
// <3> 确定构造参数的入参数量,匹配的方法的入参数量要多余它
// 方法的参数数量的最小值
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
// 从 RootBeanDefinition 解析出方法的参数个数作为最小值
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// <4> 将所有的构造方法进行排序,public 方法优先,入参个数多的优先
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历所有构造函数
for (Constructor<?> candidate : candidates) {
// 获取该构造方法的参数类型
Class<?>[] paramTypes = candidate.getParameterTypes();
// 如果前面已经找到匹配的构造方法和入参,则直接结束循环
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 如果这个构造方法的参数个数小于入参数量,则跳过
if (paramTypes.length < minNrOfArgs) {
continue;
}
// -------------------------解析出构造方法的入参-------------------------
// <5> 解析出构造方法的入参
// 保存参数的对象
ArgumentsHolder argsHolder;
// <5.2> 通过**依赖注入**获取入参
if (resolvedValues != null) {
try {
// 获取构造方法的参数名称(@ConstructorProperties 注解)
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
// 没有获取到则通过 ParameterNameDiscoverer 参数探测器获取参数名称
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
// 解析出方法的入参,参数值会被依赖注入
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 LinkedList<>();
}
causes.add(ex);
continue;
}
}
// <5.1> 如果当前方法的入参指定了参数,如果个数相等则直接使用
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
// -------------------------根据权重获取最匹配的方法-------------------------
// <6> 因为会遍历所有匹配的方法,所以需要进行权重的判断,拿到最优先的那个
// 判断解析构造函数的时候是否以宽松模式还是严格模式,默认为 true
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
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);
}
}
// <7> 没有找到对应的构造方法,则抛出异常
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);
}
// <8> 将解析出来的工厂方法和入参缓存,设置到 RootBeanDefinition 中,因为整个过程比较复杂,避免再次解析
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// <9> 调用这个构造方法返回一个实例对象(反射机制),并设置到 `bw` 中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}