Spring 3.0 提供了三种类型的转换器(Converter
、ConverterFactory
、GenericConverter
),分别用来处理 1:1、1:N、N:N 的类型转换。ConversionService
类统一管理所有的类型转换器,负责注册、查找、转换等功能,统一对外提供服务。
Example
DefaultConversionService
DefaultConversionService
是GenericConverter
子类,示例demo:
String转成Boolean:
@Test
public 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());
}
String转成List:
public static void main(String[] args) {
DefaultConversionService serivce = new DefaultConversionService();
List convert = serivce.convert("a,b,c,d", List.class);
System.out.println(convert); // [a, b, c, d]
}
Converter
是一个函数接口
@FunctionalInterface public interface Converter<S, T> {...}
Object转String:
// ObjectToStringConverter
final class ObjectToStringConverter implements Converter<Object, String> {
@Override
public String convert(Object source) {
return source.toString();
}
}
自定义数据转换器
// 把形如这样的字符串: "fsx:18" 转换为Person对象
public class PersonConverter implements Converter<String, Person> {
@Override
public Person convert(String source) {
if (StringUtils.isEmpty(source)) {
return null;
}
String[] strings = StringUtils.delimitedListToStringArray(source, ":");
Person person = new Person();
person.setName(strings[0]);
person.setAge(Integer.valueOf(strings[1]));
return person;
}
public static void main(String[] args) {
PersonConverter personConverter = new PersonConverter();
System.out.println(personConverter.convert("fsx:18")); //Person{name='fsx', age=18}
}
}
ConverterFactory
可以将对象从S转换为R的子类型(1:N),该工厂就是用来创建一个converter
,把目标类型转换成子类型,所以它是1->N的。注意:Spring内置的实现也都是外部不可访问的
public interface ConverterFactory<S, R> {
/**
* Get the converter to convert from S to target type T, where T is also an instance of R.
* @param <T> the target type
* @param targetType the target type to convert to
* @return a converter from S to T
*/
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
demo:
final class IntegerToEnumConverterFactory implements ConverterFactory<Integer, Enum> {
// ConversionUtils.getEnumType表示拿出枚举的class类型
@Override
public <T extends Enum> Converter<Integer, T> getConverter(Class<T> targetType) {
return new IntegerToEnum(ConversionUtils.getEnumType(targetType));
}
// 内部类的实现 把Integer转为Enum的子类型~~~ 相当于根据integer找到一个enum(注意此处根据角标来找的)
private class IntegerToEnum<T extends Enum> implements Converter<Integer, T> {
private final Class<T> enumType;
public IntegerToEnum(Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T convert(Integer source) {
return this.enumType.getEnumConstants()[source];
}
}
}
// StringToEnumConverterFactory 大体同上 return (T) Enum.valueOf(this.enumType, source.trim())
...
GenericConverter
用于在两个或多个类型之间转换的通用转换器接口。这是最灵活的转换器SPI接口,也是最复杂的。灵活是因为它一个转换器就能转换多个s/t,所以它是N->N的。实现类们一般情况下也会实现接口:ConditionalConverter
。
它的实现类都是子接口ConditionalGenericConverter
的实现类(就是GenericConverter和ConditionalConverter的结合)