spring学习(七)类型转换类ConversionService
来源:互联网 发布:防排烟计算软件 编辑:程序博客网 时间:2024/05/16 08:03
spring可以对不同Class类型进行相应的转换。比如String转成Boolean. Boolean转成string类.以下是个简单的例子
@Testpublic void testConverter() {DefaultConversionService serivce = new DefaultConversionService();boolean actual = serivce.canConvert(String.class, Boolean.class);Assert.assertEquals(true, actual);Object acc = serivce.convert("true", Boolean.class);Assert.assertEquals(true, ((Boolean)acc).booleanValue());}
spring类型转换涉及到的类图如下
1、spring是通过ConversionService进行类型转换,通过ConverterRegistry进行转换器注册
其中ConversionService中的方法canConverter判断是否可以转失,convert调用相应的转换器进行类型转换操作
ConverterRegistry中的方法add(Converter)是注册一个转换器
2、对于ConversionService和ConverterRegistry的主要实现类是GenericConversionService。GenericConversionService维护了一个内部类的对象Converters.
当注册一个converter时。会生成一个GenericeConverter的适配类ConverterAdapter,并注册到内部类Converters中
public void addConverter(Converter<?, ?> converter) {GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class);Assert.notNull(typeInfo, "Unable to the determine sourceType <S> and targetType " +"<T> which your Converter<S, T> converts between; declare these generic types.");addConverter(new ConverterAdapter(typeInfo, converter));}public void addConverter(Class<?> sourceType, Class<?> targetType, Converter<?, ?> converter) {GenericConverter.ConvertiblePair typeInfo = new GenericConverter.ConvertiblePair(sourceType, targetType);addConverter(new ConverterAdapter(typeInfo, converter));}public void addConverter(GenericConverter converter) {this.converters.add(converter);invalidateCache();}
内部类Converters中维护了一个Map用于存放先前注册的所有Converter
private static class Converters {private final Set<GenericConverter> globalConverters =new LinkedHashSet<GenericConverter>();private final Map<ConvertiblePair, ConvertersForPair> converters =new LinkedHashMap<ConvertiblePair, ConvertersForPair>(36);public void add(GenericConverter converter) {Set<ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();if (convertibleTypes == null) {Assert.state(converter instanceof ConditionalConverter,"Only conditional converters may return null convertible types");globalConverters.add(converter);}else {for (ConvertiblePair convertiblePair : convertibleTypes) {ConvertersForPair convertersForPair = getMatchableConverters(convertiblePair);convertersForPair.add(converter);}}}3、当调用canConvert时,会调用内部类的方法find方法查找转换的类型sourceType和targetType是否进行了注册
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {ConverterCacheKey key = new ConverterCacheKey(sourceType, targetType);GenericConverter converter = this.converterCache.get(key);if (converter != null) {return (converter != NO_MATCH ? converter : null);}converter = this.converters.find(sourceType, targetType);if (converter == null) {converter = getDefaultConverter(sourceType, targetType);}if (converter != null) {this.converterCache.put(key, converter);return converter;}this.converterCache.put(key, NO_MATCH);return null;}其中内部类Converters的find方法根据sourceType和targetType去查询Converters中维护的Map中是否包括支持的注册类型,如果存在返回GenericConverter的适配类ConverterAdapter,如果没有存在返回null
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {// Search the full type hierarchyList<Class<?>> sourceCandidates = getClassHierarchy(sourceType.getType());List<Class<?>> targetCandidates = getClassHierarchy(targetType.getType());for (Class<?> sourceCandidate : sourceCandidates) {for (Class<?> targetCandidate : targetCandidates) {ConvertiblePair convertiblePair = new ConvertiblePair(sourceCandidate, targetCandidate);GenericConverter converter = getRegisteredConverter(sourceType, targetType, convertiblePair);if(converter != null) {return converter;}}}return null;}private GenericConverter getRegisteredConverter(TypeDescriptor sourceType,TypeDescriptor targetType, ConvertiblePair convertiblePair) {// Check specifically registered convertersConvertersForPair convertersForPair = converters.get(convertiblePair);GenericConverter converter = convertersForPair == null ? null: convertersForPair.getConverter(sourceType, targetType);if (converter != null) {return converter;}// Check ConditionalGenericConverter that match all typesfor (GenericConverter globalConverter : this.globalConverters) {if (((ConditionalConverter)globalConverter).matches(sourceType, targetType)) {return globalConverter;}}return null;}
4、当查找到注册的类型转换器时GenericConverter时。会调用ConverterAdapter中的convert方法。ConverterAdapter中的convert方法会调用相当维护的converter并转换
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (source == null) {return convertNullSource(sourceType, targetType);}return this.converter.convert(source);}
5、spring的注册类型转换器时,是通过GenericConversionService的子类DefaultConversionService实现的
private static void addScalarConverters(ConverterRegistry converterRegistry) {ConversionService conversionService = (ConversionService) converterRegistry;converterRegistry.addConverter(new StringToBooleanConverter());converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());converterRegistry.addConverterFactory(new StringToNumberConverterFactory());converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());converterRegistry.addConverter(new StringToCharacterConverter());converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());converterRegistry.addConverter(new NumberToCharacterConverter());converterRegistry.addConverterFactory(new CharacterToNumberFactory());converterRegistry.addConverterFactory(new StringToEnumConverterFactory());converterRegistry.addConverter(Enum.class, String.class, new EnumToStringConverter(conversionService));converterRegistry.addConverter(new StringToLocaleConverter());converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());converterRegistry.addConverter(new PropertiesToStringConverter());converterRegistry.addConverter(new StringToPropertiesConverter());converterRegistry.addConverter(new StringToUUIDConverter());converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());}
1 0
- spring学习(七)类型转换类ConversionService
- spring 源码研究---core包-- 类型转换服务ConversionService
- spring mvc使用ConversionService转换数据
- Spring MVC 学习笔记 data binding conversionService
- 使用ConversionService转换数据
- JavaScript 学习(七):类型转换(未完成)
- Spring MVC学习(七)-------SpringMVC数据类型转换
- Spring MVC学习(七)-------SpringMVC数据类型转换
- 七类型转换
- SpringMVC使用ConversionService进行数据转换
- Spring学习笔记(七)
- Spring学习笔记(七)
- Spring学习笔记(七)
- Spring学习(七)spring整合mybatis
- Spring MVC详解(七) 注解式控制器的数据验证、类型转换及格式化(1)
- Spring MVC详解(七) 注解式控制器的数据验证、类型转换及格式化(2)
- Spring MVC详解(七) 注解式控制器的数据验证、类型转换及格式化(1)
- Spring MVC详解(七) 注解式控制器的数据验证、类型转换及格式化(2)
- GdiplusFlat(6)绘制文本
- Android中Service(服务)详解
- 谈谈iOS中Categories(分类)、Extensions(类扩展)和继承的区别
- OpenCV2:图像的几何变换,平移、镜像、缩放、旋转(2)
- 机器学习算法基础概念学习总结
- spring学习(七)类型转换类ConversionService
- jasig cas 4.0 注销后还能访问应用的问题
- HTTP协议之状态码详解
- ios 修改工程名称,程序名称(xcode6.3)
- 【思想提升】温故知新
- iOS beginAnimations 做首尾动画
- 一个声明指定了多个类型的问题
- STD::MAP与结构体的互转
- 南邮 OJ 1268 多元Huffman编码变形