100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > SpringMVC 之类型转换Converter 源代码分析

SpringMVC 之类型转换Converter 源代码分析

时间:2020-03-03 04:48:04

相关推荐

SpringMVC 之类型转换Converter 源代码分析

SpringMVC 之类型转换Converter 源代码分析

最近研究SpringMVC的类型转换器,在以往我们需要SpringMVC为我们自动进行类型转换的时候都是用的PropertyEditor。通过PropertyEditor的setAsText()方法我们可以实现字符串向特定类型的转换。但是这里有一个限制是它只支持从String类型转为其他类型。在Spring3中 引入了Converter<S, T>接口,它支持从一个Object转为另一个Object。除了Converter接口之外,实现ConverterFactory接口和GenericConverter接口也可以实现我们自己的类型转换逻辑。我们先来看一下Converter<S, T>接口的定义

public interface Converter<S, T> {T convert(S source);}

S为源对象 T为目标对象 实现该接口即可实现我们的类型转换,我们写一个最为常见的时间类型转换器

1 public class StringToDateConvert implements Converter<String, Date> { 23private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 4 5@Override 6public Date convert(String source) { 7 if(source.length() == 0) { 8 return null; 9 }10 try {11 return format.parse(source);12 } catch (ParseException e) {13 throw new RuntimeException(source + "类型转换失败");14 }15}16 17 }

在定义好Converter之后,就是使用Converter了。为了统一调用Converter进行类型转换,Spring为我们提供了一个ConversionService接口。通过实现这个接口我们可以实现自己的Converter调用逻辑。我们先来看一下ConversionService接口的定义:

public interface ConversionService {boolean canConvert(Class<?> sourceType, Class<?> targetType);

boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);<T> T convert(Object source, Class<T> targetType);Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);}

我们可以看到ConversionService接口里面定义了两个canConvert方法和两个convert方法,canConvert方法用于判断当前的ConversionService是否能够对原类型和目标类型进行转换,convert方法则是用于进行类型转换的。上面出现的参数类型TypeDescriptor是对于一种类型的封装,里面包含该种类型的值、实际类型等等信息。

一般而言我们在实现ConversionService接口的时候也会实现ConverterRegistry接口。使用ConverterRegistry可以使我们对类型转换器做一个统一的注册。ConverterRegistry接口的定义如下:

public interface ConverterRegistry {void addConverter(Converter<?, ?> converter);void addConverter(GenericConverter converter);void addConverterFactory(ConverterFactory<?, ?> converterFactory);void removeConvertible(Class<?> sourceType, Class<?> targetType);}

有了这俩个接口以后我们就可以发挥我们自己的设计能力实现里面的逻辑了。不过Spring已经为我们提供了一个实现,这个类就是GenericConversionService

首先我们看一下这个类的定义

public class GenericConversionService implements ConfigurableConversionService {}

可以看到GenericConversionService 继承至ConfigurableConversionService 接口,那ConfigurableConversionService 又是什么呢,我们在看源码

public interface ConfigurableConversionService extends ConversionService, ConverterRegistry {}

呵呵 这回清楚了吧,GenericConversionService 就是实现了ConversionService接口与ConverterRegistry接口。完成了我们类型转换器的注册 与 转换逻辑,下面我们将通过源代码来详细分析该实现的逻辑。

在分析源代码之前,让我们在看另外俩个转换器,也就是上面提到的ConverterFactory接口和GenericConverterConverterFactory接口的定义

public interface ConverterFactory<S, R> {<T extends R> Converter<S, T> getConverter(Class<T> targetType);}

我们可以看到ConverterFactory接口里面就定义了一个产生Converter的getConverter方法,参数是目标类型的class。我们可以看到ConverterFactory中一共用到了三个泛型,S、R、T,其中S表示原类型,R表示目标类型,T是类型R的一个子类。

考虑这样一种情况,我们有一个表示用户状态的枚举类型UserStatus,如果要定义一个从String转为UserStatus的Converter,根据之前Converter接口的说明,我们的StringToUserStatus大概是这个样子:

public class StringToUserStatus implements Converter<String, UserStatus> {@Overridepublic UserStatus convert(String source) {if (source == null) {return null;}return UserStatus.valueOf(source);}}

如果这个时候有另外一个枚举类型UserType,那么我们就需要定义另外一个从String转为UserType的Converter——StringToUserType,那么我们的StringToUserType大概是这个样子:

public class StringToUserType implements Converter<String, UserType> {@Overridepublic UserType convert(String source) {if (source == null) {return null;}return UserType.valueOf(source);}}

如果还有其他枚举类型需要定义原类型为String的Converter的时候,我们还得像上面那样定义对应的Converter。有了ConverterFactory之后,这一切都变得非常简单,因为UserStatus、UserType等其他枚举类型同属于枚举,所以这个时候我们就可以统一定义一个从String到Enum的ConverterFactory,然后从中获取对应的Converter进行convert操作。Spring官方已经为我们实现了这么一个StringToEnumConverterFactory:

1 @SuppressWarnings("unchecked") 2 final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> { 3 4public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) { 5 return new StringToEnum(targetType); 6} 7 8private class StringToEnum<T extends Enum> implements Converter<String, T> { 9 10 private final Class<T> enumType;11 12 public StringToEnum(Class<T> enumType) {13 this.enumType = enumType;14 }15 16 public T convert(String source) {17 if (source.length() == 0) {18// It's an empty enum identifier: reset the enum value to null.19return null;20 }21 return (T) Enum.valueOf(this.enumType, source.trim());22 }23}24 25 }

这样,如果是要进行String到UserStatus的转换,我们就可以通过StringToEnumConverterFactory实例的getConverter(UserStatus.class).convert(string)获取到对应的UserStatus,如果是要转换为UserType的话就是getConverter(UserType.class).convert(string)。这样就非常方便,可以很好的支持扩展。

看GenericConverter接口的定义GenericConverter接口是所有的Converter接口中最灵活也是最复杂的一个类型转换接口。像我们之前介绍的Converter接口只支持从一个原类型转换为一个目标类型;ConverterFactory接口只支持从一个原类型转换为一个目标类型对应的子类型;而GenericConverter接口支持在多个不同的原类型和目标类型之间进行转换,这也就是GenericConverter接口灵活和复杂的地方。我们先来看一下GenericConverter接口的定义:

1 public interface GenericConverter { 23Set<ConvertiblePair> getConvertibleTypes(); 4 5Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType); 6 7public static final class ConvertiblePair { 8 9 private final Class<?> sourceType;10 11 private final Class<?> targetType;12 13 public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {14 Assert.notNull(sourceType, "Source type must not be null");15 Assert.notNull(targetType, "Target type must not be null");16 this.sourceType = sourceType;17 this.targetType = targetType;18 }19 20 public Class<?> getSourceType() {21 return this.sourceType;22 }23 24 public Class<?> getTargetType() {25 return this.targetType;26 }27}28 29 }

我们可以看到GenericConverter接口中一共定义了两个方法,getConvertibleTypes()和convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType)。getConvertibleTypes方法用于返回这个GenericConverter能够转换的原类型和目标类型的这么一个组合;convert方法则是用于进行类型转换的,我们可以在这个方法里面实现我们自己的转换逻辑。之所以说GenericConverter是最复杂的是因为它的转换方法convert的参数类型TypeDescriptor是比较复杂的。TypeDescriptor对类型Type进行了一些封装,包括value、Field及其对应的真实类型等等,具体的可以查看API。

有了上面的基础以后就让我们一起来分析一下Spring为我们提供的GenericConversionService这个类

/*** Spring GenericConversionService 类型转换器核心源代码分析*/public class GenericConversionService implements ConfigurableConversionService {//这个转换器在没有找到对应转化器 并且 源类型与目标类型是同一种类型时使用private static final GenericConverter NO_OP_CONVERTER = new GenericConverter() {public Set<ConvertiblePair> getConvertibleTypes() {return null;}public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {//可以看到这里并没有做处理,直接将原类型返回return source;}public String toString() {return "NO_OP";}};//这个转换器在没有找到对应转化器 并且 源类型与目标类型不是同一种类型时使用。将抛出异常private static final GenericConverter NO_MATCH = new GenericConverter() {public Set<ConvertiblePair> getConvertibleTypes() {throw new UnsupportedOperationException();}public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {throw new UnsupportedOperationException();}public String toString() {return "NO_MATCH";}};// converters存放系统所有的类型转换器// 其结构为 key = sourceType ; value = Map<Class<?>, MatchableConverters>;// 至于MatchableConverters是什么 在后面会讲到// 整个converters的数据接口大概是这样的/*** 一个原类型对应一个Map<targetType<?>, MatchableConverters>数据结构* converters * [key: String value = Map<targetType<?>, MatchableConverters>]* [key: sourceType1 value = Map<targetType<?>, MatchableConverters>]* [key: sourceType2 value = Map<targetType<?>, MatchableConverters>]* * * * 一个Map<targetType<?>, MatchableConverters>数据结构包含每种目标类型对应的转换器* Map<targetType<?>, MatchableConverters>* [key:int value=MatchableConverters]* [key:targetType1 value=MatchableConverters(1)]* [key:targetType2 value=MatchableConverters(2)]* */private final Map<Class<?>, Map<Class<?>, MatchableConverters>> converters =new HashMap<Class<?>, Map<Class<?>, MatchableConverters>>(36);// 转换器缓存// 系统在对某个类型第一次做转换的时候会先去查找匹配的转换器,找到以后会放到这个数据结构之中 提高效率private final Map<ConverterCacheKey, GenericConverter> converterCache =new ConcurrentHashMap<ConverterCacheKey, GenericConverter>();//注册类型转换器 Converter接口 这个接口就是像我们上面例子里提到的StringToDateConvertpublic void addConverter(Converter<?, ?> converter) {//首先根据converter的实例 获取原类型(sourceType) 与 目标类型(targetType)的对象//关于GenericConverter.ConvertiblePair类 就是对 原类型与目标类型的一种封装GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class);if (typeInfo == null) {throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> which " +"your Converter<S, T> converts between; declare these generic types.");}//注册转换器//关于ConverterAdapter的解释 在该类上面有详细的解释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));}//最终所有的转换器 ConverterFactory,Converter,ConditionalGenericConverter 都会被转换为GenericConverter//对象进行注册 也就是说 GenericConversionService类里的转换器 最终都被包装为GenericConverter对象public void addConverter(GenericConverter converter) {//拿到GenericConverter所支持的转换类型(GenericConverter.ConvertiblePair)的集合Set<GenericConverter.ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();//循环拿出没一种 转换类型组合进行注册for (GenericConverter.ConvertiblePair convertibleType : convertibleTypes) {//将converter对象添加到MatchableConverters对象当中去 getMatchableConverters(convertibleType.getSourceType(), convertibleType.getTargetType()).add(converter);}invalidateCache();}//注册实现ConverterFactory<?, ?>接口的转换器//该方法还是将ConverterFactory的实现类包装为GenericConverter对象public void addConverterFactory(ConverterFactory<?, ?> converterFactory) {GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converterFactory, ConverterFactory.class);if (typeInfo == null) {throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetRangeType R which " +"your ConverterFactory<S, R> converts between; declare these generic types.");}addConverter(new ConverterFactoryAdapter(typeInfo, converterFactory));}//移除某种类型的转换器public void removeConvertible(Class<?> sourceType, Class<?> targetType) {getSourceConverterMap(sourceType).remove(targetType);invalidateCache();}//判断是否能够转换public boolean canConvert(Class<?> sourceType, Class<?> targetType) {if (targetType == null) {throw new IllegalArgumentException("The targetType to convert to cannot be null");} return canConvert(sourceType != null ? TypeDescriptor.valueOf(sourceType) : null, TypeDescriptor.valueOf(targetType));}//判断是否能够转换public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {if (targetType == null) {throw new IllegalArgumentException("The targetType to convert to cannot be null");}if (sourceType == null) {return true;}GenericConverter converter = getConverter(sourceType, targetType);return (converter != null);}@SuppressWarnings("unchecked")public <T> T convert(Object source, Class<T> targetType) {if (targetType == null) {throw new IllegalArgumentException("The targetType to convert to cannot be null");} return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType));}public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (targetType == null) {throw new IllegalArgumentException("The targetType to convert to cannot be null");}if (sourceType == null) {Assert.isTrue(source == null, "The source must be [null] if sourceType == [null]");return handleResult(sourceType, targetType, convertNullSource(sourceType, targetType));}if (source != null && !sourceType.getObjectType().isInstance(source)) {throw new IllegalArgumentException("The source to convert from must be an instance of " +sourceType + "; instead it was a " + source.getClass().getName());}GenericConverter converter = getConverter(sourceType, targetType);if (converter != null) {Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);return handleResult(sourceType, targetType, result);}else {return handleConverterNotFound(source, sourceType, targetType); }}/*** Convenience operation for converting a source object to the specified targetType, where the targetType is a descriptor that provides additional conversion context.* Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and encapsulates the construction of the sourceType descriptor using {@link TypeDescriptor#forObject(Object)}.* @param source the source object* @param targetType the target type* @return the converted value* @throws ConversionException if a conversion exception occurred* @throws IllegalArgumentException if targetType is null* @throws IllegalArgumentException if sourceType is null but source is not null*/public Object convert(Object source, TypeDescriptor targetType) {return convert(source, TypeDescriptor.forObject(source), targetType);}public String toString() {List<String> converterStrings = new ArrayList<String>();for (Map<Class<?>, MatchableConverters> targetConverters : this.converters.values()) {for (MatchableConverters matchable : targetConverters.values()) {converterStrings.add(matchable.toString());}}Collections.sort(converterStrings);StringBuilder builder = new StringBuilder();builder.append("ConversionService converters = ").append("\n");for (String converterString : converterStrings) {builder.append("\t");builder.append(converterString);builder.append("\n"); }return builder.toString();}// subclassing hooks/*** Template method to convert a null source.* <p>Default implementation returns <code>null</code>.* Subclasses may override to return custom null objects for specific target types.* @param sourceType the sourceType to convert from* @param targetType the targetType to convert to* @return the converted null object*/protected Object convertNullSource(TypeDescriptor sourceType, TypeDescriptor targetType) {return null;}/*** Hook method to lookup the converter for a given sourceType/targetType pair.* First queries this ConversionService's converter cache.* On a cache miss, then performs an exhaustive search for a matching converter.* If no converter matches, returns the default converter.* Subclasses may override.* @param sourceType the source type to convert from* @param targetType the target type to convert to* @return the generic converter that will perform the conversion, or <code>null</code> if no suitable converter was found* @see #getDefaultConverter(TypeDescriptor, TypeDescriptor)*/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);}else {converter = findConverterForClassPair(sourceType, targetType);if (converter == null) {converter = getDefaultConverter(sourceType, targetType);}if (converter != null) {this.converterCache.put(key, converter);return converter;}else {this.converterCache.put(key, NO_MATCH);return null;}}}/*** Return the default converter if no converter is found for the given sourceType/targetType pair.* Returns a NO_OP Converter if the sourceType is assignable to the targetType.* Returns <code>null</code> otherwise, indicating no suitable converter could be found.* Subclasses may override.* @param sourceType the source type to convert from* @param targetType the target type to convert to* @return the default generic converter that will perform the conversion*/protected GenericConverter getDefaultConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {return (sourceType.isAssignableTo(targetType) ? NO_OP_CONVERTER : null);}//通过反射的到Converter<S, T>接口的 S与T 封装成GenericConverter.ConvertiblePair对象返回private GenericConverter.ConvertiblePair getRequiredTypeInfo(Object converter, Class<?> genericIfc) {Class<?>[] args = GenericTypeResolver.resolveTypeArguments(converter.getClass(), genericIfc);return (args != null ? new GenericConverter.ConvertiblePair(args[0], args[1]) : null);}private MatchableConverters getMatchableConverters(Class<?> sourceType, Class<?> targetType) {//通过sourceType(原类型)在converters当中获取Map<Class<?>, MatchableConverters>对象Map<Class<?>, MatchableConverters> sourceMap = getSourceConverterMap(sourceType);//在Map<Class<?>, MatchableConverters>对象当中根据targetType(目标类型)获取MatchableConverters对象MatchableConverters matchable = sourceMap.get(targetType);if (matchable == null) {matchable = new MatchableConverters();sourceMap.put(targetType, matchable);}return matchable;}private void invalidateCache() {this.converterCache.clear();}//通过sourceType(原类型)在converters当中获取Map<Class<?>, MatchableConverters>private Map<Class<?>, MatchableConverters> getSourceConverterMap(Class<?> sourceType) {Map<Class<?>, MatchableConverters> sourceMap = converters.get(sourceType);//为null就创建一个if (sourceMap == null) {sourceMap = new HashMap<Class<?>, MatchableConverters>();this.converters.put(sourceType, sourceMap);}return sourceMap;}private GenericConverter findConverterForClassPair(TypeDescriptor sourceType, TypeDescriptor targetType) {Class<?> sourceObjectType = sourceType.getObjectType();if (sourceObjectType.isInterface()) {LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();classQueue.addFirst(sourceObjectType);while (!classQueue.isEmpty()) {Class<?> currentClass = classQueue.removeLast();Map<Class<?>, MatchableConverters> converters = getTargetConvertersForSource(currentClass);GenericConverter converter = getMatchingConverterForTarget(sourceType, targetType, converters);if (converter != null) {return converter;}Class<?>[] interfaces = currentClass.getInterfaces();for (Class<?> ifc : interfaces) {classQueue.addFirst(ifc);}}Map<Class<?>, MatchableConverters> objectConverters = getTargetConvertersForSource(Object.class);return getMatchingConverterForTarget(sourceType, targetType, objectConverters);}else if (sourceObjectType.isArray()) {LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();classQueue.addFirst(sourceObjectType);while (!classQueue.isEmpty()) {Class<?> currentClass = classQueue.removeLast();Map<Class<?>, MatchableConverters> converters = getTargetConvertersForSource(currentClass);GenericConverter converter = getMatchingConverterForTarget(sourceType, targetType, converters);if (converter != null) {return converter;}Class<?> componentType = ClassUtils.resolvePrimitiveIfNecessary(currentClass.getComponentType());if (componentType.getSuperclass() != null) {classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass());}else if (componentType.isInterface()) {classQueue.addFirst(Object[].class);}}return null;}else {HashSet<Class<?>> interfaces = new LinkedHashSet<Class<?>>();LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();classQueue.addFirst(sourceObjectType);while (!classQueue.isEmpty()) {Class<?> currentClass = classQueue.removeLast();Map<Class<?>, MatchableConverters> converters = getTargetConvertersForSource(currentClass);GenericConverter converter = getMatchingConverterForTarget(sourceType, targetType, converters);if (converter != null) {return converter;}Class<?> superClass = currentClass.getSuperclass();if (superClass != null && superClass != Object.class) {classQueue.addFirst(superClass);}for (Class<?> interfaceType : currentClass.getInterfaces()) {addInterfaceHierarchy(interfaceType, interfaces);}}for (Class<?> interfaceType : interfaces) {Map<Class<?>, MatchableConverters> converters = getTargetConvertersForSource(interfaceType);GenericConverter converter = getMatchingConverterForTarget(sourceType, targetType, converters);if (converter != null) {return converter;}}Map<Class<?>, MatchableConverters> objectConverters = getTargetConvertersForSource(Object.class);return getMatchingConverterForTarget(sourceType, targetType, objectConverters);}}private Map<Class<?>, MatchableConverters> getTargetConvertersForSource(Class<?> sourceType) {Map<Class<?>, MatchableConverters> converters = this.converters.get(sourceType);if (converters == null) {converters = Collections.emptyMap();}return converters;}private GenericConverter getMatchingConverterForTarget(TypeDescriptor sourceType, TypeDescriptor targetType,Map<Class<?>, MatchableConverters> converters) {Class<?> targetObjectType = targetType.getObjectType();if (targetObjectType.isInterface()) {LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();classQueue.addFirst(targetObjectType);while (!classQueue.isEmpty()) {Class<?> currentClass = classQueue.removeLast();MatchableConverters matchable = converters.get(currentClass);GenericConverter converter = matchConverter(matchable, sourceType, targetType);if (converter != null) {return converter;}Class<?>[] interfaces = currentClass.getInterfaces();for (Class<?> ifc : interfaces) {classQueue.addFirst(ifc);}}return matchConverter(converters.get(Object.class), sourceType, targetType);}else if (targetObjectType.isArray()) {LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();classQueue.addFirst(targetObjectType);while (!classQueue.isEmpty()) {Class<?> currentClass = classQueue.removeLast();MatchableConverters matchable = converters.get(currentClass);GenericConverter converter = matchConverter(matchable, sourceType, targetType);if (converter != null) {return converter;}Class<?> componentType = ClassUtils.resolvePrimitiveIfNecessary(currentClass.getComponentType());if (componentType.getSuperclass() != null) {classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass());}else if (componentType.isInterface()) {classQueue.addFirst(Object[].class);}}return null;}else {Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();classQueue.addFirst(targetObjectType);while (!classQueue.isEmpty()) {Class<?> currentClass = classQueue.removeLast();MatchableConverters matchable = converters.get(currentClass);GenericConverter converter = matchConverter(matchable, sourceType, targetType);if (converter != null) {return converter;}Class<?> superClass = currentClass.getSuperclass();if (superClass != null && superClass != Object.class) {classQueue.addFirst(superClass);}for (Class<?> interfaceType : currentClass.getInterfaces()) {addInterfaceHierarchy(interfaceType, interfaces);}}for (Class<?> interfaceType : interfaces) {MatchableConverters matchable = converters.get(interfaceType);GenericConverter converter = matchConverter(matchable, sourceType, targetType);if (converter != null) {return converter;}}return matchConverter(converters.get(Object.class), sourceType, targetType);}}private void addInterfaceHierarchy(Class<?> interfaceType, Set<Class<?>> interfaces) {interfaces.add(interfaceType);for (Class<?> inheritedInterface : interfaceType.getInterfaces()) {addInterfaceHierarchy(inheritedInterface, interfaces);}}private GenericConverter matchConverter(MatchableConverters matchable, TypeDescriptor sourceFieldType, TypeDescriptor targetFieldType) {if (matchable == null) {return null;}return matchable.matchConverter(sourceFieldType, targetFieldType);}private Object handleConverterNotFound(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (source == null) {assertNotPrimitiveTargetType(sourceType, targetType);return source;}else if (sourceType.isAssignableTo(targetType) && targetType.getObjectType().isInstance(source)) {return source;}else {throw new ConverterNotFoundException(sourceType, targetType);} }private Object handleResult(TypeDescriptor sourceType, TypeDescriptor targetType, Object result) {if (result == null) {assertNotPrimitiveTargetType(sourceType, targetType);}return result;}private void assertNotPrimitiveTargetType(TypeDescriptor sourceType, TypeDescriptor targetType) {if (targetType.isPrimitive()) {throw new ConversionFailedException(sourceType, targetType, null,new IllegalArgumentException("A null value cannot be assigned to a primitive type"));} }//包装我们的Converter类 将我们的Converter类的实例 包装成为GenericConverter对象 以便统一注册@SuppressWarnings("unchecked")private final class ConverterAdapter implements GenericConverter {//原类型(sourceType) 与 目标类型(targetType)private final ConvertiblePair typeInfo;//我们实现Converter<S,T>接口的转换器private final Converter<Object, Object> converter;//构造函数public ConverterAdapter(ConvertiblePair typeInfo, Converter<?, ?> converter) {this.converter = (Converter<Object, Object>) converter;this.typeInfo = typeInfo;}//返回一个Set 里面包含了当前ConverterAdapter对象能够转换的类型信息public Set<ConvertiblePair> getConvertibleTypes() {return Collections.singleton(this.typeInfo);}public boolean matchesTargetType(TypeDescriptor targetType) {return this.typeInfo.getTargetType().equals(targetType.getObjectType());}//具体转换逻辑public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (source == null) {return convertNullSource(sourceType, targetType);}//拿到实现Converter<S,T>接口的转换器进行转换return this.converter.convert(source);}public String toString() {return this.typeInfo.getSourceType().getName() + " -> " + this.typeInfo.getTargetType().getName() +" : " + this.converter.toString();}}//包装我们的Converter类 将我们的ConverterFactory类的实例 包装成为GenericConverter对象 以便统一注册@SuppressWarnings("unchecked")private final class ConverterFactoryAdapter implements GenericConverter {//原类型(sourceType) 与 目标类型(targetType)private final ConvertiblePair typeInfo;//实现了ConverterFactory接口的类对象private final ConverterFactory<Object, Object> converterFactory;public ConverterFactoryAdapter(ConvertiblePair typeInfo, ConverterFactory<?, ?> converterFactory) {this.converterFactory = (ConverterFactory<Object, Object>) converterFactory;this.typeInfo = typeInfo;}//返回一个Set 里面包含了当前ConverterAdapter对象能够转换的类型信息public Set<ConvertiblePair> getConvertibleTypes() {return Collections.singleton(this.typeInfo);}//转换逻辑public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (source == null) {return convertNullSource(sourceType, targetType);}//通过ConverterFactory的getConverter拿到转换器对象在进行转换return this.converterFactory.getConverter(targetType.getObjectType()).convert(source);}public String toString() {return this.typeInfo.getSourceType().getName() + " -> " + this.typeInfo.getTargetType().getName() +" : " + this.converterFactory.toString();}}private static class MatchableConverters {//支持条件的转换器private LinkedList<ConditionalGenericConverter> conditionalConverters;//默认转换器private GenericConverter defaultConverter;public void add(GenericConverter converter) {if (converter instanceof ConditionalGenericConverter) {if (this.conditionalConverters == null) {this.conditionalConverters = new LinkedList<ConditionalGenericConverter>();}this.conditionalConverters.addFirst((ConditionalGenericConverter) converter);}else {this.defaultConverter = converter;}}//匹配转换器public GenericConverter matchConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {//如果conditionalConverters转换器不为空 那么优先查找if (this.conditionalConverters != null) {for (ConditionalGenericConverter conditional : this.conditionalConverters) {//通过matches方法进行匹配 如果匹配到了则返回该转换器if (conditional.matches(sourceType, targetType)) {return conditional;}}}//判断是不是ConverterAdapter 如果是这调用matchesTargetType方法看是否能够转换if (this.defaultConverter instanceof ConverterAdapter) {ConverterAdapter adapter = (ConverterAdapter) this.defaultConverter;if (!adapter.matchesTargetType(targetType)) {return null;}}//返回转换器return this.defaultConverter;}public String toString() {if (this.conditionalConverters != null) {StringBuilder builder = new StringBuilder();for (Iterator<ConditionalGenericConverter> it = this.conditionalConverters.iterator(); it.hasNext();) {builder.append(it.next());if (it.hasNext()) {builder.append(", ");}}if (this.defaultConverter != null) {builder.append(", ").append(this.defaultConverter);}return builder.toString();}else {return this.defaultConverter.toString();}}}private static final class ConverterCacheKey {private final TypeDescriptor sourceType;private final TypeDescriptor targetType;public ConverterCacheKey(TypeDescriptor sourceType, TypeDescriptor targetType) {this.sourceType = sourceType;this.targetType = targetType;}public boolean equals(Object other) {if (this == other) {return true;}if (!(other instanceof ConverterCacheKey)) {return false;}ConverterCacheKey otherKey = (ConverterCacheKey) other;return this.sourceType.equals(otherKey.sourceType) && this.targetType.equals(otherKey.targetType);}public int hashCode() {return this.sourceType.hashCode() * 29 + this.targetType.hashCode();}public String toString() {return "ConverterCacheKey [sourceType = " + this.sourceType + ", targetType = " + this.targetType + "]";}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。