• @value


     

     

     通过name来获取bean对象。

     

     这一点eclipse就没有intelliJ好,拉到方法内部上面就不现实方法名了,这里是上面调用的方法的内部。

     

     

    处理内部属性:

     然后就在这里抛出异常了:

     我们打个debug看看:

     

     因为上面这个是循环处理,所以我们一直等到:

    不为空:

     我们进入下面的方法里看看:

     不过貌似这个和我们哪个异常没有关系:

    一不小心按跳过了。。。

    我们继续吧:

    也不是这个:

     但是我们跟着走一遍没错的,然后在循环到报错的看就更清楚了:

    这个跟上个不一样,这个是方法:

     

     这个类挺有意思:

     我们先来看看是哪个方法有注入需求:

     下面这个应该就是核心方法了:

    我们进入看看:

     

    几组判断后进入下面方法:

     

     

    return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);

    一个很简单的判断:

    没看清跳出来了:

     又是一个非常大的方法,这就是spring。

    跳出吧,我们继续我们的找异常之旅:

    过了几十个,终于找到你了:

     这个是个属性注入,@value嘛:

     

    然后我们进入下一行代码:

    value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

    接着调用:DefaultListableBeanFacotory的方法doResolveDependency

        @Override
        public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
                Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    
            descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
            if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
                return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
            }
            else if (ObjectFactory.class == descriptor.getDependencyType()) {
                return new DependencyObjectFactory(descriptor, beanName);
            }
            else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
                return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
            }
            else {
                Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
                if (result == null) {
                    result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
                }
                return result;
            }
        }
    
        public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
                Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    
            Class<?> type = descriptor.getDependencyType();
         //获取注解@value的值 Object value
    = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } if (type.isArray()) { Class<?> componentType = type.getComponentType(); DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof Object[]) { Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans)); } return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getCollectionType(); if (elementType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); } return null; } DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof List) { Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans)); } return result; } else if (Map.class.isAssignableFrom(type) && type.isInterface()) { Class<?> keyType = descriptor.getMapKeyType(); if (String.class != keyType) { if (descriptor.isRequired()) { throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() + "] must be [java.lang.String]"); } return null; } Class<?> valueType = descriptor.getMapValueType(); if (valueType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); } return null; } DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(type, "", descriptor); } return null; } if (matchingBeans.size() > 1) { String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (primaryBeanName == null) { throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet()); } if (autowiredBeanNames != null) { autowiredBeanNames.add(primaryBeanName); } return matchingBeans.get(primaryBeanName); } // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); if (autowiredBeanNames != null) { autowiredBeanNames.add(entry.getKey()); } return entry.getValue(); } }

    所以我怀疑在上面的地方开始处理@value的值,这里关系到后面的只是${env.isdev}还是true

    ========

    Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);

    可能有很多annotations吧

    然后就到了find..

     

    注意这是的value值已经是“${env.isDev}”了。

    所以我们分析完这个===中的内容了。

    ========

    我们由上面标黄的代码进入:

      //org.springframework.beans.TypeConverterDelegate
    /** * Convert the value to the specified required type. * @param newValue the proposed new value * @param requiredType the type we must convert to * (or {@code null} if not known, for example in case of a collection element) * @param methodParam the method parameter that is the target of the conversion * (may be {@code null}) * @return the new value, possibly the result of type conversion * @throws IllegalArgumentException if type conversion failed */ public <T> T convertIfNecessary(Object newValue, Class<T> requiredType, MethodParameter methodParam) throws IllegalArgumentException { return convertIfNecessary(null, null, newValue, requiredType, (methodParam != null ? new TypeDescriptor(methodParam) : TypeDescriptor.valueOf(requiredType))); }

    里面只有一个方法:

        /**
         * Convert the value to the required type (if necessary from a String),
         * for the specified property.
         * @param propertyName name of the property
         * @param oldValue the previous value, if available (may be {@code null})
         * @param newValue the proposed new value
         * @param requiredType the type we must convert to
         * (or {@code null} if not known, for example in case of a collection element)
         * @param typeDescriptor the descriptor for the target property or field
         * @return the new value, possibly the result of type conversion
         * @throws IllegalArgumentException if type conversion failed
         */
        @SuppressWarnings("unchecked")
        public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
                Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {
    
            // Custom editor for this type?
            PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
    
            ConversionFailedException conversionAttemptEx = null;
    
            // No custom editor but custom ConversionService specified?
            ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
            if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
                TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
                if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
                    try {
                        return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
                    }
                    catch (ConversionFailedException ex) {
                        // fallback to default conversion logic below
                        conversionAttemptEx = ex;
                    }
                }
            }
        //根据debug直接进入了下面这个判断
            Object convertedValue = newValue;
    
            // Value not of required type?
            if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
                if (typeDescriptor != null && requiredType != null && Collection.class.isAssignableFrom(requiredType) &&
                        convertedValue instanceof String) {
                    TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor();
                    if (elementTypeDesc != null && Enum.class.isAssignableFrom(elementTypeDesc.getType())) {
                        convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
                    }
                }
                if (editor == null) {
                    editor = findDefaultEditor(requiredType);
                }
                convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
            }
    
            boolean standardConversion = false;
    
            if (requiredType != null) {
                // Try to apply some standard type conversion rules if appropriate.
    
                if (convertedValue != null) {
                    if (Object.class == requiredType) {
                        return (T) convertedValue;
                    }
                    else if (requiredType.isArray()) {
                        // Array required -> apply appropriate conversion of elements.
                        if (convertedValue instanceof String && Enum.class.isAssignableFrom(requiredType.getComponentType())) {
                            convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
                        }
                        return (T) convertToTypedArray(convertedValue, propertyName, requiredType.getComponentType());
                    }
                    else if (convertedValue instanceof Collection) {
                        // Convert elements to target type, if determined.
                        convertedValue = convertToTypedCollection(
                                (Collection<?>) convertedValue, propertyName, requiredType, typeDescriptor);
                        standardConversion = true;
                    }
                    else if (convertedValue instanceof Map) {
                        // Convert keys and values to respective target type, if determined.
                        convertedValue = convertToTypedMap(
                                (Map<?, ?>) convertedValue, propertyName, requiredType, typeDescriptor);
                        standardConversion = true;
                    }
                    if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) {
                        convertedValue = Array.get(convertedValue, 0);
                        standardConversion = true;
                    }
                    if (String.class == requiredType && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) {
                        // We can stringify any primitive value...
                        return (T) convertedValue.toString();
                    }
                    else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) {
                        if (conversionAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) {
                            try {
                                Constructor<T> strCtor = requiredType.getConstructor(String.class);
                                return BeanUtils.instantiateClass(strCtor, convertedValue);
                            }
                            catch (NoSuchMethodException ex) {
                                // proceed with field lookup
                                if (logger.isTraceEnabled()) {
                                    logger.trace("No String constructor found on type [" + requiredType.getName() + "]", ex);
                                }
                            }
                            catch (Exception ex) {
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Construction via String failed for type [" + requiredType.getName() + "]", ex);
                                }
                            }
                        }
                        String trimmedValue = ((String) convertedValue).trim();
                        if (requiredType.isEnum() && "".equals(trimmedValue)) {
                            // It's an empty enum identifier: reset the enum value to null.
                            return null;
                        }
                        convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue);
                        standardConversion = true;
                    }
                    else if (convertedValue instanceof Number && Number.class.isAssignableFrom(requiredType)) {
                        convertedValue = NumberUtils.convertNumberToTargetClass(
                                (Number) convertedValue, (Class<Number>) requiredType);
                        standardConversion = true;
                    }
                }
                else {
                    // convertedValue == null
                    if (javaUtilOptionalEmpty != null && requiredType.equals(javaUtilOptionalEmpty.getClass())) {
                        convertedValue = javaUtilOptionalEmpty;
                    }
                }
    
                if (!ClassUtils.isAssignableValue(requiredType, convertedValue)) {
                    if (conversionAttemptEx != null) {
                        // Original exception from former ConversionService call above...
                        throw conversionAttemptEx;
                    }
                    else if (conversionService != null) {
                        // ConversionService not tried before, probably custom editor found
                        // but editor couldn't produce the required type...
                        TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
                        if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
                            return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
                        }
                    }
    
                    // Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
                    StringBuilder msg = new StringBuilder();
                    msg.append("Cannot convert value of type [").append(ClassUtils.getDescriptiveType(newValue));
                    msg.append("] to required type [").append(ClassUtils.getQualifiedName(requiredType)).append("]");
                    if (propertyName != null) {
                        msg.append(" for property '").append(propertyName).append("'");
                    }
                    if (editor != null) {
                        msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
                                "] returned inappropriate value of type [").append(
                                ClassUtils.getDescriptiveType(convertedValue)).append("]");
                        throw new IllegalArgumentException(msg.toString());
                    }
                    else {
                        msg.append(": no matching editors or conversion strategy found");
                        throw new IllegalStateException(msg.toString());
                    }
                }
            }
    
            if (conversionAttemptEx != null) {
                if (editor == null && !standardConversion && requiredType != null && Object.class != requiredType) {
                    throw conversionAttemptEx;
                }
                logger.debug("Original ConversionService attempt failed - ignored since " +
                        "PropertyEditor based conversion eventually succeeded", conversionAttemptEx);
            }
    
            return (T) convertedValue;
        }

    注意上面的红箭头,我们需要适配的类型是Bloolean类型。

    这里的convertedvalue是一个string对象。

    继续:

     进入第二个判断:

    if (requiredType != null && !requiredType.isArray() && convertedValue instanceof String[])

    很显然"${env.isDev}"不是一个string[]类型。

    最终进入第三组判断,这次对了:

     由最开始的异常跟踪我们知道,就是在这里抛的异常了。

    Object org.springframework.beans.TypeConverterDelegate.doConvertTextValue(Object oldValue, String newTextValue, PropertyEditor editor)

     三个参数oldValue, newTextValue, editor的值分别是,null,${env.isDev},org.springframework.beans.propertyeditors.CustomBooleanEditor@7c1447b5

     

    就是这里了

     

     最后没有一个匹配上的就爆异常了。

     所以我怀疑那里的参数是不对的。

    我现在这里打个端点,方便等会直接到这里查看:

  • 相关阅读:
    软件工程期末考试复习(五)
    软件工程期末考试复习(四)
    软件工程期末考试复习(三)
    软件工程期末考试复习(二)
    shell脚本与mongo交互
    python使用单例模式创建MySQL链接
    python with上下文的浅谈
    Docker 基础概念科普 和 常用操作介绍
    MySQL聚集索引和非聚集索引
    为什么选择Python
  • 原文地址:https://www.cnblogs.com/guazi/p/6698654.html
Copyright © 2020-2023  润新知