Insight spring @Value 注入处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tt50335971/article/details/52599760

经常使用@Value,有空正好Insight spring怎样实现Value表达式解析并注入的?

...

场景:properties配置key-value,然后@Value(value = "${key}") String config;

...

Insight 核心处理,过程直接参考源码:

/**
 * 解析依赖value-处理
 * 1.优先处理@Value
 * 2.处理其余的依赖value
 * 3.最后处理自定义的@Autowired依赖实例value
 **/
protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName, Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
	// 1.1 解析@Value 配置的value
    Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
    if (value != null) {
        if (value instanceof String) {
            // 1.2 计算placeholder 类型的value
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
            // 1.3 计算EL 表达式
            value = evaluateBeanDefinitionString(strVal, bd);
        }
        TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
        // 1.4 value 类型转换
        return (descriptor.getField() != null ?	converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
    }
    // ...
	
}
其中涉及到的具体实现类列表:

首先getSuggestedValue,得到的配置型的value eg:${config},或者#{tom.age}
--@see QualifierAnnotationAutowireCandidateResolver
然后真正的value 值解析,
--@see PlaceholderResolvingStringValueResolver implements StringValueResolver
最后需要根据value 进行convert eg: Integer

--@see TypeConverterDelegate
--@see CustomNumberEditor.setAsTex
--转换的实现 NumberUtils.parseNumbe

...

另外:spring 支持各种类型转换的PropertyEditor,基本上可以随心所欲的注入配置:

/**
 * Actually register the default editors for this registry instance.
 */
private void createDefaultEditors() {
    this.defaultEditors = new HashMap, PropertyEditor>(64);
    
    // Simple editors, without parameterization capabilities.
    // The JDK does not contain a default editor for any of these target types.
    this.defaultEditors.put(Charset.class, new CharsetEditor());
    this.defaultEditors.put(Class.class, new ClassEditor());
    this.defaultEditors.put(Class[].class, new ClassArrayEditor());
    this.defaultEditors.put(Currency.class, new CurrencyEditor());
    this.defaultEditors.put(File.class, new FileEditor());
    this.defaultEditors.put(InputStream.class, new InputStreamEditor());
    this.defaultEditors.put(InputSource.class, new InputSourceEditor());
    this.defaultEditors.put(Locale.class, new LocaleEditor());
    this.defaultEditors.put(Pattern.class, new PatternEditor());
    this.defaultEditors.put(Properties.class, new PropertiesEditor());
    this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
    this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
    this.defaultEditors.put(URI.class, new URIEditor());
    this.defaultEditors.put(URL.class, new URLEditor());
    this.defaultEditors.put(UUID.class, new UUIDEditor());
    
    // Default instances of collection editors.
    // Can be overridden by registering custom instances of those as custom editors.
    this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
    this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
    this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
    this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
    this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));
    
    // Default editors for primitive arrays.
    this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
    this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());
    
    // The JDK does not contain a default editor for char!
    this.defaultEditors.put(char.class, new CharacterEditor(false));
    this.defaultEditors.put(Character.class, new CharacterEditor(true));
    
    // Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
    this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
    this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));
    
    // The JDK does not contain default editors for number wrapper types!
    // Override JDK primitive number editors with our own CustomNumberEditor.
    this.defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
    this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
    this.defaultEditors.put(short.class, new CustomNumberEditor(Short.class, false));
    this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
    this.defaultEditors.put(int.class, new CustomNumberEditor(Integer.class, false));
    this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
    this.defaultEditors.put(long.class, new CustomNumberEditor(Long.class, false));
    this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
    this.defaultEditors.put(float.class, new CustomNumberEditor(Float.class, false));
    this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
    this.defaultEditors.put(double.class, new CustomNumberEditor(Double.class, false));
    this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
    this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
    this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));
    
    // Only register config value editors if explicitly requested.
    if (this.configValueEditorsActive) {
    	StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
    	this.defaultEditors.put(String[].class, sae);
    	this.defaultEditors.put(short[].class, sae);
    	this.defaultEditors.put(int[].class, sae);
    	this.defaultEditors.put(long[].class, sae);
    }
}



阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页