Insight spring @Value 注入处理

原创 2016年09月20日 21:03:44

经常使用@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);
    }
}



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

spring cloud与spring boot实战

本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。 请加QQ群:274033905(群名:《spring cloud 实战》),免费获取课件资料哦 本课程的知识目录和思维导图详细介绍地址:http://blog.csdn.net/bobo0218bo/article/details/78442245
  • 2017年10月15日 20:49

使用spring 的注解 @value使用方法

有三种,都没测试 1 中################# 在spring 3.0中,可以通过使用@value,对一些如xxx.properties文件  中的文件,进行键值对的注入,例子如下:  ...
  • jintianhen1
  • jintianhen1
  • 2015-01-23 09:30:21
  • 2062

用spring@Value注解实现常量功能

之前的博客中提到过如何通过 java.util.ResourceBundle 和 java.util.Properties 类通过读取 key-value文件的形式实现常量功能。其实 spring 已...
  • zhugeyangyang1994
  • zhugeyangyang1994
  • 2016-03-24 16:23:05
  • 7135

工作积累(五)——使用spring@Value注解实现常量功能

之前的博客中提到过如何通过 java.util.ResourceBundle 和 java.util.Properties 类通过读取 key-value 文件的形式实现常量功能。其实 spring ...
  • tk175009666
  • tk175009666
  • 2015-07-21 20:49:03
  • 481

Spring@value用法

 Spring@value用法为了简化读取properties文件中的配置值,spring支持@value注解的方式来获取,这种方式大大简化了项目配置,提高业务中的灵活性。一、两种使用方法1、@Val...
  • lph2017
  • lph2017
  • 2018-03-05 10:49:28
  • 52

Spring注入值(Value注解)

背景Spring开发过程中经常遇到需要把特殊的值注入到成员变量里,比如普通值、文件、网址、配置信息、系统 变量等等。Spring主要使用注解@Value把对应的值注入到变量中。 常用的注入类型有以下...
  • feigeswjtu
  • feigeswjtu
  • 2017-07-05 15:19:05
  • 970

Spring @Value 用法小结,#与$的区别

文章转载自:http://www.cnblogs.com/larryzeal/p/5910149.html 起因 一直的用法是 @Value("${jdbc.driverClass}") ...
  • wltsysterm
  • wltsysterm
  • 2017-04-01 11:09:00
  • 3075

spring(基础10) 注解@Value详解

一 配置方式 @value需要参数,这里参数可以是两种形式: @Value("#{configProperties['t1.msgname']}")或者@Value("${t1.msgname}"...
  • zengdeqing2012
  • zengdeqing2012
  • 2016-02-25 11:15:56
  • 30578

Spring通过@Value注解注入属性的几种方式

场景假如有以下属性文件dev.properties, 需要注入下面的tagtag=123通过PropertyPlaceholderConfigurer ...
  • csujiangyu
  • csujiangyu
  • 2016-03-21 12:45:50
  • 20567

spring 3.1.13中新增的util @value注解,给类或方法注入值

在spring 3.0中,可以通过使用@value,对一些如xxx.properties文件  中的文件,进行键值对的注入,例子如下:  1 首先在applicationContext.xml...
  • qing419925094
  • qing419925094
  • 2014-09-26 11:46:51
  • 3397
收藏助手
不良信息举报
您举报文章:Insight spring @Value 注入处理
举报原因:
原因补充:

(最多只允许输入30个字)