bean的创建第三部分 bean工厂方法参数的解析
Posted honger
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于bean的创建第三部分 bean工厂方法参数的解析的主要内容,如果未能解决你的问题,请参考以下文章
创建在类路径资源[applicationcontext]中定义名为“工厂”的bean时出错。:在设置bean属性“dataSource”时,无法解析对bean“dataSource”的引用;嵌套异常是