zoukankan      html  css  js  c++  java
  • bean的创建(五)第三部分 bean工厂方法参数的解析

    准备好一系列参数之后,开始参数类型的转换,方法参数的对应。
    ConstructorResolver.createArgumentArray
    
    private ArgumentsHolder createArgumentArray(
                String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues,
                BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Object methodOrCtor,
                boolean autowiring) throws UnsatisfiedDependencyException {
    
            String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
    //获取类型转换器    
        TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
                    this.beanFactory.getCustomTypeConverter() : bw);
    
            ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
    //用于储存可以使用的参数
            Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
                    new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length);
            Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
    
            for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
                Class<?> paramType = paramTypes[paramIndex];
                String paramName = (paramNames != null ? paramNames[paramIndex] : null);
                // Try to find matching constructor argument value, either indexed or generic.
     //尝试从indexed和generic集合中寻找符合条件的参数,indexed可以根据参数下标获取,没有指定下标的可以更具参数名或者参数的类型去获取。
                ConstructorArgumentValues.ValueHolder 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).
    //如果没有找到,使用通过的值,什么都没有指定的,就指定了一个值的参数
                if (valueHolder == null && !autowiring) {
                    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集合中
                    usedValueHolders.add(valueHolder);
    //获取原始的值,这个值可能是某个bean,还没有进行类型转换
                    Object originalValue = valueHolder.getValue();
                    Object convertedValue;
    //如果已经进行了转换的,存入预备参数中
                    if (valueHolder.isConverted()) {
                        convertedValue = valueHolder.getConvertedValue();
                        args.preparedArguments[paramIndex] = convertedValue;
                    }
                    else {
    //如果没有被转换过,那么就进行类型转换
                        ConstructorArgumentValues.ValueHolder sourceHolder =
                                (ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
    //获取最原始的值,比如一个BeanRuntimeReference。
                        Object sourceValue = sourceHolder.getValue();
                        try {
                            convertedValue = converter.convertIfNecessary(originalValue, paramType,
                                    MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex));
                            // TODO re-enable once race condition has been found (SPR-7423)
                            /*
    //如果最原始的值和经过解析后的参数一致,那么就将最原始的ValueHolder的已转换的值设置成类型转换后的值,表示这个转化后的值就是通过当前valueholder的值转化后的值,并把转化后的值设置都预备参数数组中,值得注意的是,这段代码被注释掉了
                            if (originalValue == sourceValue || sourceValue instanceof TypedStringValue) {
                                // Either a converted value or still the original one: store converted value.
                                sourceHolder.setConvertedValue(convertedValue);
                                args.preparedArguments[paramIndex] = convertedValue;
                            }
                            else {
                            */
    //标记参数已经被解析,并将最原始的值设置给了预备参数集合
                                args.resolveNecessary = true;
                                args.preparedArguments[paramIndex] = sourceValue;
                            // }
                        }
                        catch (TypeMismatchException ex) {
                            throw new UnsatisfiedDependencyException(
                                    mbd.getResourceDescription(), beanName, paramIndex, paramType,
                                    "Could not convert " + methodType + " argument value of type [" +
                                    ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
                                    "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
                        }
                    }
    //保存类型转换后的参数,和未进行类型转换的参数
                    args.arguments[paramIndex] = convertedValue;
                    args.rawArguments[paramIndex] = originalValue;
                }
    
    //如果没有找到匹配的参数,那么就进行自动装配,自动装配通过参数类型去BeanFactory去寻找符合类型的bean或者是用@Value注解修饰的
                else {
                    // 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, paramIndex, paramType,
                                "Ambiguous " + methodType + " argument types - " +
                                "did you specify the correct bean references as " + methodType + " arguments?");
                    }
                    try {
                        MethodParameter param = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
    //自动装配,这里和对preparedArguments参数的自动装配是一样的解析方法。
                        Object autowiredArgument = resolveAutowiredArgument(param, beanName, autowiredBeanNames, converter);
                        args.rawArguments[paramIndex] = autowiredArgument;
                        args.arguments[paramIndex] = autowiredArgument;
    //标记这个参数是通过自动装配获取的
                        args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
                        args.resolveNecessary = true;
                    }
                    catch (BeansException ex) {
                        throw new UnsatisfiedDependencyException(
                                mbd.getResourceDescription(), beanName, paramIndex, paramType, ex);
                    }
                }
            }
    //注册依赖,记录当前beanName依赖的bean的name,用于检测循环依赖
            for (String autowiredBeanName : autowiredBeanNames) {
                this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
                if (this.beanFactory.logger.isDebugEnabled()) {
                    this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName +
                            "' via " + methodType + " to bean named '" + autowiredBeanName + "'");
                }
            }
    
            return args;
        }
  • 相关阅读:
    vue本地项目静态资源管理
    vue-resource的使用
    查看Python已安装的模块
    getpass密码输入模块
    css之浮动
    Linux之常用命令和部分解析
    css之vertical-align(盒子垂直对齐方式)
    Octave 里的 fminunc
    Octave /Matlab--Control Statements:for,while, if statement----Coursera ML笔记
    Octave环境的安装
  • 原文地址:https://www.cnblogs.com/honger/p/10389856.html
Copyright © 2011-2022 走看看