Spring Type Conversion
在Spring framework 3之后加入了core.convert包,这个包可以代替PropertyEditor来帮助我们将输入转换成我们需要的变量类型
1 Convert SPI
Spring提供了下面的top interface实现转换
package org.springframework.core.convert.converter;
public interface Converter<S, T> {
T convert(S source);
}
需要注意的是必须保证Converter
的线程安全,以及如果转换失败的话spring
建议抛出IllegalArgumentException
,同时保证输入的S必须部位null
2 Using ConverterFactory
如果想要统一管理Converter
Spring也提供了相关接口
package org.springframework.core.convert.converter;
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
一官方实现类为例StringToEnumConverterFactory
package org.springframework.core.convert.support;
final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnumConverter(targetType);
}
private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> {
private Class<T> enumType;
public StringToEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
public T convert(String source) {
return (T) Enum.valueOf(this.enumType, source.trim());
}
}
}
3 使用GenericConverter
如果想要更加通用的Converter可以使用GenericConverter
来实现
package org.springframework.core.convert.converter;
public interface GenericConverter {
public Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
getConvertibleTypes()
这个方法返回GenericConverter
可以转换的source->target对。
这个接口Spring也有相应的实现例子ArrayToCollectionConverter
可以参考由于GenericConverter
过于复杂Spring建议还是使用之前提到的两种方式,即Converter
和ConverterFactory
4 The ConversionService API
package org.springframework.core.convert;
public interface ConversionService {
boolean canConvert(Class<?> sourceType, Class<?> targetType);
<T> T convert(Object source, Class<T> targetType);
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
从ConversionService
接口的方法不难看出,他可以帮助我们判断类型是否能够转换。一般而言ConversionService
会和ConverterRegistry
一起使用这样,这样在内部形成一个Converter
的代理,然后直接实现类型转换,Spring也给我们提供了例如GenericConversionService
的例子
5 Configuring a ConversionService
ConversionService
最好设计成没有状态,因为他会在Spring的多线程环境中使用。
6 Using a ConversionService Programmatically
@Service
public class MyService {
@Autowired
public MyService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public void doIt() {
this.conversionService.convert(...)
}
}
一般建议使用DefaultConversionService
这里面提供了很多的类型转换功能