/** * Instantiate the bean using a named factory method. The method may be static, if the * mbd parameter specifies a class, rather than a factoryBean, or an instance variable * on a factory object itself configured using Dependency Injection. * 使用 FactoryMethod实例化bean */ protected BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { //创建一个工厂委托类ConstructorResolver并进行工厂的实例化 returnnewConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); }
/** * Instantiate the bean using a named factory method. The method may be static, if the * bean definition parameter specifies a class, rather than a "factory-bean", or * an instance variable on a factory object itself configured using Dependency Injection. * <p>Implementation requires iterating over the static or instance methods with the * name specified in the RootBeanDefinition (the method may be overloaded) and trying * to match with the parameters. We don't have the types attached to constructor args, * so trial and error is the only way to go here. The explicitArgs array may contain * argument values passed in programmatically via the corresponding getBean method. * 通过工厂委托类进行实例化bean * * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param explicitArgs argument values passed in programmatically via the getBean * method, or {@code null} if none (-> use constructor argument values from bean definition) * @return a BeanWrapper for the new instance */ public BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { //1. 创建BeanWrapper的实现类 BeanWrapperImplbw=newBeanWrapperImpl(); //2. 初始化 BeanWrapperImpl // 向BeanWrapper对象中添加 ConversionService 对象和属性编辑器 PropertyEditor 对象 this.beanFactory.initBeanWrapper(bw);
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);
// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式 // 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常 // 宽松模式:使用具有"最接近的模式"进行匹配 // typeDiffWeight:类型差异权重 inttypeDiffWeight= (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 = newLinkedHashSet<>(); ambiguousFactoryMethods.add(factoryMethodToUse); } ambiguousFactoryMethods.add(candidate); } } }
// 没有可执行的工厂方法,抛出异常 if (factoryMethodToUse == null || argsToUse == null) { if (causes != null) { UnsatisfiedDependencyExceptionex= causes.removeLast(); for (Exception cause : causes) { this.beanFactory.onSuppressedException(cause); } throw ex; } List<String> argTypes = newArrayList<>(minNrOfArgs); if (explicitArgs != null) { for (Object arg : explicitArgs) { argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null"); } } elseif (resolvedValues != null) { Set<ValueHolder> valueHolders = newLinkedHashSet<>(resolvedValues.getArgumentCount()); valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values()); valueHolders.addAll(resolvedValues.getGenericArgumentValues()); for (ValueHolder value : valueHolders) { StringargType= (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null")); argTypes.add(argType); } } StringargDesc= StringUtils.collectionToCommaDelimitedString(argTypes); thrownewBeanCreationException(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()) { thrownewBeanCreationException(mbd.getResourceDescription(), beanName, "Invalid factory method '" + mbd.getFactoryMethodName() + "': needs to have a non-void return type!"); } elseif (ambiguousFactoryMethods != null) { thrownewBeanCreationException(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); }