/** * 当前线程,正在创建的 Bean 对象的名字 * * The name of the currently created bean, for implicit dependency registration * on getBean etc invocations triggered from a user-specified Supplier callback. */ privatefinal NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
// <3> if (factoryMethodToUse == null || argsToUse == null) { // Need to determine the factory method... // Try all methods with this name to see if they match the given arguments. // 获取工厂方法的类全名称 factoryClass = ClassUtils.getUserClass(factoryClass);
int minNrOfArgs; if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { // We don't have arguments passed in programmatically, so we need to resolve the // arguments specified in the constructor arguments held in the bean definition. // <2.3> getBean() 没有传递参数,则需要解析保存在 BeanDefinition 构造函数中指定的参数 if (mbd.hasConstructorArgumentValues()) { // 构造函数的参数 ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); // 解析构造函数的参数 // 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } else { minNrOfArgs = 0; } }
// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式 // 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常 // 宽松模式:使用具有"最接近的模式"进行匹配 // typeDiffWeight:类型差异权重 int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // Choose this factory method if it represents the closest match. // 代表最接近的类型匹配,则选择作为构造函数 if (typeDiffWeight < minTypeDiffWeight) { factoryMethodToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousFactoryMethods = null; } // Find out about ambiguity: In case of the same type difference weight // for methods with the same number of parameters, collect such candidates // and eventually raise an ambiguity exception. // However, only perform that check in non-lenient constructor resolution mode, // and explicitly ignore overridden methods (with the same parameter signature). // 如果具有相同参数数量的方法具有相同的类型差异权重,则收集此类型选项 // 但是,仅在非宽松构造函数解析模式下执行该检查,并显式忽略重写方法(具有相同的参数签名) elseif (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"); } } elseif (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); thrownew 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") + "."); } elseif (void.class == factoryMethodToUse.getReturnType()) { thrownew BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid factory method '" + mbd.getFactoryMethodName() + "': needs to have a non-void return type!"); } elseif (ambiguousFactoryMethods != null) { thrownew 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); }
#instantiateUsingFactoryMethod(...) 方法,实在是太大了,处理细节感觉很复杂,LZ是硬着头皮看完的,中间断断续续的。吐槽这里的代码风格,完全不符合我们前面看的 Spring 代码风格。Spring 的一贯做法是将一个复杂逻辑进行拆分,分为多个细小的模块进行嵌套,每个模块负责一部分功能,模块与模块之间层层嵌套,上一层一般都是对下一层的总结和概括,这样就会使得每一层的逻辑变得清晰易懂。
/** Common lock for the four constructor fields below. */ final Object constructorArgumentLock = new Object(); // 构造函数的缓存锁
/** Package-visible field for caching the resolved constructor or factory method. */ @Nullable Executable resolvedConstructorOrFactoryMethod; // 缓存已经解析的构造函数或者工厂方法
/** Package-visible field that marks the constructor arguments as resolved. */ boolean constructorArgumentsResolved = false; // 标记字段,标记构造函数、参数已经解析了。默认为 `false` 。
/** Package-visible field for caching fully resolved constructor arguments. */ @Nullable Object[] resolvedConstructorArguments; // 缓存已经解析的构造函数参数,包可见字段。
/** Package-visible field for caching partly prepared constructor arguments. */ @Nullable Object[] preparedConstructorArguments;
然后,在对其进行排序处理(AutowireUtils.sortFactoryMethods(candidates))。排序的主要目的,是为了能够更加方便的找到匹配的构造函数,因为构造函数的确认是根据参数个数确认的。排序的规则是:先按照 public / 非 public 构造函数升序,再按照构造参数数量降序。