前言
想找一个简化版本的 spring 接口设计用来学习(包含关键设计, 如拦截器链、配置、前后置处理器等), 奈何实例不允许, 所以记下知识碎片先行学习。
类型转换
spring在org.springframework.core.convert.converter包中定义了三种类型转换器接口:Converter、ConverterFactory、GenericConverter。
一、Converter
1 2 3 4 5
| @FunctionalInterface public interface Converter<S, T> { @Nullable T convert(S source); }
|
Converter能将S类型的对象转换为T类型的对象,比如将String类型的对象转换为Integer类型的对象的实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class StringToIntegerConverter implements Converter<String, Integer> {
@Override public Integer convert(String source) { return Integer.valueOf(source); }
public static void main(String[] args) { StringToIntegerConverter converter = new StringToIntegerConverter(); Integer convert = converter.convert("123"); System.out.println(convert); } }
|
二、ConverterFactory
1 2 3
| public interface ConverterFactory<S, R> { <T extends R> Converter<S, T> getConverter(Class<T> targetType); }
|
Converter<S,T>接口适合一对一的类型转换,如果要将String类型转换为Ineger/Long/Float/Double/Decimal等类型,就要实现一系列的StringToInteger/StringToLongConverter/StringToFloatConverter转换器,非常不优雅。
ConverterFactory接口则适合一对多的类型转换,可以将一种类型转换为另一种类型及其子类。比如将String类型转换为Ineger/Long/Float/Double/Decimal等Number类型时,只需定义一个ConverterFactory转换器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class StringToNumberConverterFactory implements ConverterFactory<String, Number> {
@Override public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) { return new StringToNumber<>(targetType); }
private static final class StringToNumber<T extends Number> implements Converter<String, T> {
private final Class<T> targetType;
public StringToNumber(Class<T> targetType) { this.targetType = targetType; }
@Override public T convert(String source) { if (source.length() == 0) { return null; }
if (targetType.equals(Integer.class)) { return (T) Integer.valueOf(source); } else if (targetType.equals(Long.class)) { return (T) Long.valueOf(source); }
else { throw new IllegalArgumentException( "Cannot convert String [" + source + "] to target class [" + targetType.getName() + "]"); } } }
public static void main(String[] args) { StringToNumberConverterFactory stringToNumberConverterFactory = new StringToNumberConverterFactory(); Converter<String, Integer> converter = stringToNumberConverterFactory.getConverter(Integer.class); Integer convert = converter.convert("123"); System.out.println(convert); } }
|
三、GenericConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class StringToBooleanConverter implements GenericConverter { @Override public Set<ConvertiblePair> getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(String.class, Boolean.class)); }
@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return Boolean.valueOf((String) source); }
public static void main(String[] args) { Object aTrue = new StringToBooleanConverter().convert("true", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Boolean.class)); System.out.println(aTrue); } }
|