通过factory-method创建Bean实例(推断factory-method)

1.代码入口AbstractAutowireCapableBeanFactory#createBeanInstance

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        //返回mbd中真实bean的Class对象。
        Class beanClass = resolveBeanClass(mbd, beanName);

        //三个条件想表达的意思:bd中如果nonPublicAccessAllowed字段值为true,表示class是非公开类型的 也可以创建实例,反之false,说明是无法创建的..
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }

        // InstanceSupplier
        Supplier instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        //bean标签中配置了 factory-method的情况处理
        // bd中提供了factoryMethodName属性,那么要使用工厂方法的方式来创建对象,
        // 工厂方法又会区分静态工厂方法跟实例工厂方法
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }
    protected BeanWrapper instantiateUsingFactoryMethod(
            String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

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

ConstructorResolver用来解析构造函数跟工厂方法的代理者,并且它是通过参数匹配的方式来进行推断构造方法或者工厂方法。

2.ConstructorResolver#instantiateUsingFactoryMethod核心流程

核心流程:

  • step1.到这里已经得到了一个BeanWrapper,并对这个BeanWrapper做了初始化
  • step2.明确了实例化当前这个Bean到底是静态工厂还是实例工厂
  • step3.从缓存中取过了对应了方法以及参数
  • step4.明确了方法需要的最小的参数数量并对配置文件中的标签属性进行了一次解析
  • step5.到这里已经确定了可以使用来实例化Bean的方法是哪个
  • step6.对推断出来的方法做验证(不能为null,方法不能有多个,返回值不能为void)
  • step7.反射调用对应方法进行实例化
    // beanName:当前要实例化的Bean的名称
    // mbd:当前要实例化的Bean对应的BeanDefinition
    // explicitArgs:这个参数在容器启动阶段我们可以认定它就是null,只有显示的调用了getBean方法,
    // 并且传入了明确的参数,例如:getBean(“dmzService”,“hello”)这种情况下才会不为null
    public BeanWrapper instantiateUsingFactoryMethod(
            String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

        // BeanWrapperImpl包装了一个实例化好的对象
        // BeanWrapperImpl能够对属性进行类型转换
        BeanWrapperImpl bw = new BeanWrapperImpl();
        this.beanFactory.initBeanWrapper(bw);

        Object factoryBean;
        Class factoryClass;
        // 静态工厂方法或者是实例的工厂方法
        boolean isStatic;

        String factoryBeanName = mbd.getFactoryBeanName();
        // 如下区分是静态工厂方法还是实例的工厂方法
        // CASE1-实例的工厂方法
        if (factoryBeanName != null) {
            if (factoryBeanName.equals(beanName)) {
                throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                        "factory-bean reference points back to the same bean definition");
            }
            // 获得该实例
            factoryBean = this.beanFactory.getBean(factoryBeanName);
            if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
                throw new ImplicitlyAppearedSingletonException();
            }
            factoryClass = factoryBean.getClass();
            isStatic = false;
        }
        // CASE2-静态工厂方法
        else {
            // It's a static factory method on the bean 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;
        }
        // 在原型模式下,我们会多次创建一个Bean,所以Spring对参数以及所使用的方法做了缓存
        // 在第二次创建原型对象的时候会进入这段缓存的逻辑
        // 但是这里有个问题,为什么Spring对参数有两个缓存呢?
        // 一:resolvedConstructorArguments
        // 二:preparedConstructorArguments
        // 这里主要是因为,如果直接使用解析好的构造的参数,因为这样会导致创建出来的所有Bean都引用同一个属性
        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) {
                        argsToResolve = mbd.preparedConstructorArguments;
                    }
                }
            }
            if (argsToResolve != null) {
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
            }
        }

        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.
            // 如果被cglib代理的话,获取父类的class
            factoryClass = ClassUtils.getUserClass(factoryClass);

            List candidates = null;
            if (mbd.isFactoryMethodUnique) {
                if (factoryMethodToUse == null) {
                    factoryMethodToUse = mbd.getResolvedFactoryMethod();
                }
                if (factoryMethodToUse != null) {
                    candidates = Collections.singletonList(factoryMethodToUse);
                }
            }
            if (candidates == null) {
                candidates = new ArrayList<>();
                // 获取到工厂类中的所有方法,接下来要一步步从这些方法中筛选出来符合要求的方法
                Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
                for (Method candidate : rawCandidates) {
                    // 第一步筛选:之前 在第二段代码中已经推断了方法是静态或者非静态的
                    // 所以这里第一个要求就是要满足静态/非静态这个条件
                    // 第二个要求就是必须符合bd中定义的factoryMethodName的名称
                    // 其中第二个要求请注意,如果bd是一个configurationClassBeanDefinition,
                    // 也就是说是通过扫描@Bean注解产生的,那么在判断时还会添加是否标注了@Bean注解
                    if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
                        candidates.add(candidate);
                    }
                }
            }

            if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
                Method uniqueCandidate = candidates.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;
                }
            }

            // 优先级:public > 非public,参数多 > 参数少
            if (candidates.size() > 1) {  // explicitly skip immutable singletonList
                candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
            }

            // 用来保存从配置文件中解析出来的参数
            ConstructorArgumentValues resolvedValues = null;
            // 是否使用了自动注入,本段代码中没有使用到这个属性
            boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
            int minTypeDiffWeight = Integer.MAX_VALUE;
            // 可能出现多个符合要求的方法,用这个集合保存,实际上如果这个集合有值,就会抛出异常了
            Set ambiguousFactoryMethods = null;

            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.
                // 就是说配置文件中指定了要使用的参数,那么需要对其进行解析,
                // 解析后的值就存储在resolvedValues这个集合中
                if (mbd.hasConstructorArgumentValues()) {
                    // 通过解析constructor-arg标签,将参数封装成了ConstructorArgumentValues
                    ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                    resolvedValues = new ConstructorArgumentValues();
                    // 解析标签中的属性,类似进行类型转换
                    minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
                } else {
                    minNrOfArgs = 0;
                }
            }

            // 保存在创建方法参数数组过程中发生的异常,如果最终没有找到合适的方法,
            // 那么将这个异常信息封装后抛出
            LinkedList causes = null;

            for (Method candidate : candidates) {
                int parameterCount = candidate.getParameterCount();

                // 候选的方法的参数必须要大于推断出来的最小参数个数
                if (parameterCount >= minNrOfArgs) {
                    ArgumentsHolder argsHolder;

                    Class[] paramTypes = candidate.getParameterTypes();
                    if (explicitArgs != null) {
                        // Explicit arguments given -> arguments length must match exactly.
                        if (paramTypes.length != explicitArgs.length) {
                            continue;
                        }
                        argsHolder = new ArgumentsHolder(explicitArgs);
                    } else {
                        // Resolved constructor arguments: type conversion and/or autowiring necessary.
                        try {
                            // 获取参数的具体名字
                            String[] paramNames = null;
                            ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                            if (pnd != null) {
                                paramNames = pnd.getParameterNames(candidate);
                            }
                            // 根据方法的参数名称以及配置文件中配置的参数
                            // 创建一个参数数组用于执行工厂方法
                            argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
                                    paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
                        } catch (UnsatisfiedDependencyException ex) {
                            // 在创建参数数组的时候可能发生异常,这个时候的异常不能直接抛出,要确保所有的候选方法遍历完成,
                            // 只要有一个方法符合要求即可,但是如果遍历完所有方法还是没找到合适的构造器,那么直接抛出这些异常
                            if (logger.isTraceEnabled()) {
                                logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
                            }
                            // Swallow and try next overloaded factory method.
                            if (causes == null) {
                                causes = new LinkedList<>();
                            }
                            causes.add(ex);
                            continue;
                        }
                    }

                    // 计算类型差异
                    // 首先判断bd中是宽松模式还是严格模式,
                    // 目前看来只有@Bean标注的方法解析得到的Bean会使用严格模式来计算类型差异,
                    // 其余都是使用宽松模式
                    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).
                    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);
                    }
                }
            }

            // 对推断出来的方法做验证
            // 1.推断出来的方法不能为null
            // 2.推断出来的方法返回值不能为void
            // 3.推断出来的方法不能有多个
            if (factoryMethodToUse == null || argsToUse == null) {
                if (causes != null) {
                    UnsatisfiedDependencyException ex = causes.removeLast();
                    for (Exception cause : causes) {
                        this.beanFactory.onSuppressedException(cause);
                    }
                    throw ex;
                }
                List argTypes = new ArrayList<>(minNrOfArgs);
                if (explicitArgs != null) {
                    for (Object arg : explicitArgs) {
                        argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
                    }
                } else if (resolvedValues != null) {
                    Set 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);
            }

            if (explicitArgs == null && argsHolderToUse != null) {
                mbd.factoryMethodToIntrospect = factoryMethodToUse;
                // 对参数进行缓存,原型可能会多次调用
                argsHolderToUse.storeCache(mbd, factoryMethodToUse);
            }
        }

        // 反射调用对应方法进行实例化
        // 1.获取InstantiationStrategy,主要就是SimpleInstantiationStrategy
        // 跟CglibSubclassingInstantiationStrategy,
        // 其中CglibSubclassingInstantiationStrategy主要是用来处理
        // beanDefinition中的lookupMethod跟replaceMethod。
        // 通常来说我们使用的就是SimpleInstantiationStrategy
        // 2.SimpleInstantiationStrategy就是单纯的通过反射调用方法
        bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
        return bw;
    }

3.BeanWrapperImpl是啥?

核心有两点:

  • BeanWrapperImpl包装了一个实例化好的对象
  • BeanWrapperImpl能够对属性进行类型转换

4.参数解析

    // 方法目的:解析配置文件中指定的方法参数
    // beanName:bean名称
    // mbd:beanName对应的beanDefinition
    // bw:通过它进行类型转换
    // ConstructorArgumentValues cargs:解析标签得到的属性,还没有经过解析(类型转换)
    // ConstructorArgumentValues resolvedValues:已经经过解析的参数
    // 返回值:返回方法需要的最小参数个数
    private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
                                            ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

        // 是否有定制的类型转换器,没有的话直接使用BeanWrapper进行类型转换
        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        TypeConverter converter = (customConverter != null ? customConverter : bw);
        // 构造一个BeanDefinitionValueResolver,专门用于解析constructor-arg中的
        // value属性,实际上还包括ref属性,内嵌bean标签等等
        BeanDefinitionValueResolver valueResolver =
                new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);

        // minNrOfArgs 记录执行方法要求的最小参数个数,一般情况下就是等于constructor-arg标签指定的参数数量
        int minNrOfArgs = cargs.getArgumentCount();

        for (Map.Entry entry : cargs.getIndexedArgumentValues().entrySet()) {
            int index = entry.getKey();
            if (index < 0) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Invalid constructor argument index: " + index);
            }
            // 假设A方法直接在配置文件中指定了index=3上要使用的参数,那么这个时候A方法至少需要4个参数
            // 但是其余的3个参数可能不是通过constructor-arg标签指定的,
            // 而是直接自动注入进来的,那么在配置文件中我们就只配置了index=3上的参数,
            // 也就是说 int minNrOfArgs = cargs.getArgumentCount() + 1,
            // 这个时候 index=3,minNrOfArgs=1, 所以 minNrOfArgs = 3+1
            if (index + 1 > minNrOfArgs) {
                minNrOfArgs = index + 1;
            }
            ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
            // 如果已经转换过了,直接添加到resolvedValues集合中
            if (valueHolder.isConverted()) {
                resolvedValues.addIndexedArgumentValue(index, valueHolder);
            } else {
                // 解析value/ref/内嵌bean标签等
                Object resolvedValue =
                        valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
                // 将解析后的resolvedValue封装成一个新的ValueHolder,
                // 并将其source设置为解析constructor-arg得到的那个ValueHolder,
                // 后期会用到这个属性进行判断
                ConstructorArgumentValues.ValueHolder resolvedValueHolder =
                        new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
                resolvedValueHolder.setSource(valueHolder);
                resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
            }
        }

        // 对getGenericArgumentValues进行解析,代码基本一样
        for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
            if (valueHolder.isConverted()) {
                resolvedValues.addGenericArgumentValue(valueHolder);
            } else {
                Object resolvedValue =
                        valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
                ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
                        resolvedValue, valueHolder.getType(), valueHolder.getName());
                resolvedValueHolder.setSource(valueHolder);
                resolvedValues.addGenericArgumentValue(resolvedValueHolder);
            }
        }

        return minNrOfArgs;
    }

最终的解析逻辑就在resolveValueIfNecessary这个方法中

    // 这个方法的目的就是将解析constructor-arg标签得到的value值进行一次解析
    // 在解析标签时ref属性会被封装为RuntimeBeanReference,那么在这里进行解析时就会去调用getBean
    // 在解析value属性会会被封装为TypedStringValue,那么这里会尝试去进行一个转换
    // 关于标签的解析可以去看看org.springframework.beans.factory.xml.
    // BeanDefinitionParserDelegate#parsePropertyValue
    @Nullable
    public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
        // We must check each value to see whether it requires a runtime reference
        // to another bean to be resolved.
        // 解析constructor-arg标签中的ref属性,实际就是调用了getBean
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            return resolveReference(argName, ref);
        }
        ...

        /**
         * 
         *    
         *     1
         *    
         * 
         * 通过上面set标签中的value-type属性对value进行类型转换,
         * 如果value-type属性为空,那么这里不会进行类型转换
         */
        else if (value instanceof TypedStringValue) {
            // Convert value to target type here.
            TypedStringValue typedStringValue = (TypedStringValue) value;
            Object valueObject = evaluate(typedStringValue);
            try {
                Class resolvedTargetType = resolveTargetType(typedStringValue);
                if (resolvedTargetType != null) {
                    return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
                }
                else {
                    return valueObject;
                }
            }
            catch (Throwable ex) {
                // Improve the message by showing the context.
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Error converting typed String value for " + argName, ex);
            }
        }
        else if (value instanceof NullBean) {
            return null;
        }
        else {
            return evaluate(value);
        }
    }

5.createArgumentArray从解析出来的参数中查找当前的这个候选方法需要的参数或者自动注入

    /**
     * Create an array of arguments to invoke a constructor or factory method,
     * given the resolved constructor argument values.
     *   * beanName:要实例化的Bean的名称
     *   * mbd:对应Bean的BeanDefinition
     *   * resolvedValues:从配置文件中解析出来的并尝试过类型转换的参数
     *   * bw:在这里主要就是用作类型转换器
     *   * paramTypes:当前遍历到的候选的方法的参数类型数组
     *   * paramNames:当前遍历到的候选的方法的参数名称
     *   * executable:当前遍历到的候选的方法
     *   * autowiring:是否时自动注入
     *
     *   从解析出来的参数中查找当前的这个候选方法需要的参数。如果找到了,
     *   那么尝试对其进行类型转换,将其转换成符合方法要求的类型,
     *   如果没有找到那么还需要判断当前方法的这个参数能不能进行自动注入,如果可以自动注入的话,
     *   那么调用getBean得到需要的Bean,并将其注入到方法需要的参数中。
     */
    private ArgumentsHolder createArgumentArray(
            String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
            BeanWrapper bw, Class[] paramTypes, @Nullable String[] paramNames, Executable executable,
            boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {

        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        TypeConverter converter = (customConverter != null ? customConverter : bw);

        ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
        Set usedValueHolders = new HashSet<>(paramTypes.length);
        Set autowiredBeanNames = new LinkedHashSet<>(4);

        // 遍历候选方法的参数,跟据方法实际需要的类型到resolvedValues中去匹配
        // paramTypes:当前遍历到的候选的方法的参数类型数组
        for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
            Class paramType = paramTypes[paramIndex];
            String paramName = (paramNames != null ? paramNames[paramIndex] : "");
            // Try to find matching constructor argument value, either indexed or generic.
            ConstructorArgumentValues.ValueHolder valueHolder = null;
            if (resolvedValues != null) {
                // 首先,根据方法参数的下标到resolvedValues中找对应的下标的属性
                // 如果没找到再根据方法的参数名/类型去resolvedValues查找
                valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
                // If we couldn't find a direct match and are not supposed to autowire,
                // let's try the next generic, untyped argument value as fallback:
                // it could match after type conversion (for example, String -> int).
                // 如果都没找到
                // 1.是自动注入并且方法的参数长度正好跟配置中的参数数量相等
                // 2.不是自动注入
                // 那么按照顺序依次选取
                if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
                    valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
                }
            }
            // 也就是说在配置的参数中找到了合适的值可以应用于这个方法上
            if (valueHolder != null) {
                // We found a potential match - let's give it a try.
                // Do not consider the same value definition multiple times!
                // 防止同一个参数被应用了多次
                usedValueHolders.add(valueHolder);
                Object originalValue = valueHolder.getValue();
                Object convertedValue;
                // 已经进行过类型转换就不会需要再次进行类型转换
                if (valueHolder.isConverted()) {
                    convertedValue = valueHolder.getConvertedValue();
                    args.preparedArguments[paramIndex] = convertedValue;
                } else {
                    // 尝试将配置的值转换成方法参数需要的类型
                    MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                    try {
                        // 进行类型转换
                        convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
                    } catch (TypeMismatchException ex) {
                        throw new UnsatisfiedDependencyException(
                                mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                                "Could not convert argument value of type [" +
                                        ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
                                        "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
                    }
                    Object sourceHolder = valueHolder.getSource();
                    if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
                        Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
                        args.resolveNecessary = true;
                        args.preparedArguments[paramIndex] = sourceValue;
                    }
                }
                args.arguments[paramIndex] = convertedValue;
                args.rawArguments[paramIndex] = originalValue;
            } else {
                // 方法执行需要参数,但是resolvedValues中没有提供这个参数,
                // 也就是说这个参数是要自动注入到Bean中的
                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                // No explicit match found: we're either supposed to autowire or
                // have to fail creating an argument array for the given constructor.
                // 不是自动注入,直接抛出异常
                if (!autowiring) {
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                            "Ambiguous argument values for parameter of type [" + paramType.getName() +
                                    "] - did you specify the correct bean references as arguments?");
                }
                try {
                    // 自动注入的情况下,调用getBean获取需要注入的Bean
                    Object autowiredArgument = resolveAutowiredArgument(
                            methodParam, beanName, autowiredBeanNames, converter, fallback);
                    // 把getBean返回的Bean封装到本次方法执行时需要的参数数组中去
                    args.rawArguments[paramIndex] = autowiredArgument;
                    args.arguments[paramIndex] = autowiredArgument;
                    args.preparedArguments[paramIndex] = autowiredArgumentMarker;
                    // 自动注入的情况下,在第二次调用时,需要重新处理,不能直接缓存
                    args.resolveNecessary = true;
                } catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
                }
            }
        }

        // 注册Bean之间的依赖关系
        for (String autowiredBeanName : autowiredBeanNames) {
            this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
            if (logger.isDebugEnabled()) {
                logger.debug("Autowiring by type from bean name '" + beanName +
                        "' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
                        " to bean named '" + autowiredBeanName + "'");
            }
        }

        return args;
    }

你可能感兴趣的:(通过factory-method创建Bean实例(推断factory-method))