目录
一、介绍和Demo
ConversionService 是一个 用于类型转换的服务接口,ConversionService 整个涉及的类如下:
本次主要分析下图部分:
1.1 demo
public static void main(String[] args) {
ConversionService conversionService = new DefaultConversionService();
// String ==> Integer
Integer num = conversionService.convert("12345", int.class);
System.out.println(num);
// boolean ==> String
String s = conversionService.convert(false, String.class);
System.out.println(s);
//String ==>List
List<String> arrays = conversionService.convert("1,2,3", List.class);
System.out.println(arrays);
}
结果如下,实现了转换
12345
false
[1, 2, 3]
二、源码分析
2.1 ConversionService
ConversionService 一共就四个方法,主要就是 是否能够转换,以及对于的转换方法,有一个 参数 是TypeDescriptor是对于一种类型的封装,里面包含该类型的name、是否是基础类型、集合等判断信息
public interface ConversionService {
/**
* 是否能够进行转换
*/
boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);
boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
/**
* 进行转换
*/
@Nullable
<T> T convert(@Nullable Object source, Class<T> targetType);
@Nullable
Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
}
2.2 ConfigurableConversionService
这个接口主要就是 继承了 ConversionService, ConverterRegistry 这两个接口
public interface ConfigurableConversionService extends ConversionService, ConverterRegistry {
}
2.3 ConverterRegistry
这个主要是 注册 或者移除相关的类型转换器,主要方法如下:
public interface ConverterRegistry {
void addConverter(Converter<?, ?> converter);
<S, T> void addConverter(Class<S> sourceType, Class<T> targetType, Converter<? super S, ? extends T> converter);
void addConverter(GenericConverter converter);
void addConverterFactory(ConverterFactory<?, ?> factory);
void removeConvertible(Class<?> sourceType, Class<?> targetType);
}
2.3 GenericConversionService
GenericConversionService 是一个通用的类型转换的基本实现,适用于大部分的情况
2.3.1 内部类
GenericConversionService 类里面有好几个内部类,有一个 Converters 类
- Converters 类–管理在服务中注册的所有转换器, 后面解析一下相关具体的方法
- ConverterAdapter —将 convert 转换为 GenericConverter
- ConverterFactoryAdapter— 将 ConverterFactory 转换为对应的GenericConverter (ConverterFactory 就是一个转换器的工厂,可以将对象从S转换为R的子类型)
- ConverterCacheKey—与转换器缓存一起使用的key
- ConvertersForPair— 管理通过ConvertiblePair 注册的转换器
2.3.2 addConverter
添加注入Converter
public void addConverter(Converter<?, ?> converter) {
// 获取对应的soruce、target 类型
ResolvableType[] typeInfo = getRequiredTypeInfo(converter.getClass(), Converter.class);
// 如果对应的 类型为空,并且converter 是代理,再一次获取
if (typeInfo == null && converter instanceof DecoratingProxy) {
typeInfo = getRequiredTypeInfo(((DecoratingProxy) converter).getDecoratedClass(), Converter.class);
}
// 如果 source、target 为null ,就抛出异常
if (typeInfo == null) {
throw new IllegalArgumentException("Unable to determine source type <S> and target type <T> for your " +
"Converter [" + converter.getClass().getName() + "]; does the class parameterize those types?");
}
// 添加到内部类 Converters 里面 进行管理
addConverter(new ConverterAdapter(converter, typeInfo[0], typeInfo[1]));
}
@Override
public void addConverter(GenericConverter converter) {
// 加到 GenericConversionService 自定义的类 converters里面
this.converters.add(converter);
// 将缓存清空
invalidateCache();
}
2.3.3 getConverter
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
// 根据sourceType、targetType 获取对应的KEy
//ConverterCacheKey 重写了equals、hashCode ,这样比较时,就是 比较的 sourceType 和 targetType 是否一致
ConverterCacheKey key = new ConverterCacheKey(sourceType, targetType);
// 从缓存获取
GenericConverter converter = this.converterCache.get(key);
// 如果不为null, 是 NO_MATCH 就返回 null
if (converter != null) {
return (converter != NO_MATCH ? converter : null);
}
//从 converters 里面查找 converter
converter = this.converters.find(sourceType, targetType);
// 如果为 null ,就返回默认的设置
if (converter == null) {
converter = getDefaultConverter(sourceType, targetType);
}
// 放入缓存,如果converter 为null,value就设置为
if (converter != null) {
this.converterCache.put(key, converter);
return converter;
}
this.converterCache.put(key, NO_MATCH);
return null;
}
2.3.4 内部类 Converters
这里的 Converters 是专门负责管理在服务中注册的所有转换器,下面看一下几个具体的方法
2.3.4.1 find
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
// 获取所有的 target、source 的层次结构
List<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;
}
2.3 DefaultConversionService
DefaultConversionService 里面主要就是对 一系列的 converter 进行注册, 在构造函数里面直接调用 addDefaultConverters
/**
* Create a new {@code DefaultConversionService} with the set of
* {@linkplain DefaultConversionService#addDefaultConverters(ConverterRegistry) default converters}.
*/
public DefaultConversionService() {
addDefaultConverters(this);
}
三、总结
ConversionService 这块就是 将 source、target 进行转换,并且提供了很多的对应的类型转换方法.