该软件包提供了一个通用的类型转换系统。系统定义
一个用于实现类型转换逻辑的 SPI 和一个用于执行类型转换的 API
运行。在 Spring 容器中,您可以使用此系统作为实现的替代方法,将外部化的 Bean 属性值字符串转换为
必需的属性类型。您还可以在应用程序中的任何位置使用公共 API
需要类型转换的地方。core.convert
PropertyEditor
转换器 SPI
实现类型转换逻辑的SPI简单且类型强大,如下所示 接口定义显示:
package org.springframework.core.convert.converter;
public interface Converter<S, T> {
T convert(S source);
}
要创建您自己的转换器,请实现接口并参数化为要转换的类型和要转换为的类型。您也可以透明地应用这样的
转换器(如果集合或数组需要
转换为 的数组或集合,前提是委托数组或集合
转换器也已注册(默认情况下会注册)。Converter
S
T
S
T
DefaultConversionService
对于每次调用 ,都保证 source 参数不为 null。如果转换失败,您可以抛出任何未经检查的异常。具体来说,它应该抛出一个来报告无效的源值。
请注意确保您的实现是线程安全的。convert(S)
Converter
IllegalArgumentException
Converter
软件包中提供了多个转换器实现,如
一种便利。其中包括从字符串到数字和其他常见类型的转换器。
下面的列表显示了该类,这是一个典型的实现:core.convert.support
StringToInteger
Converter
package org.springframework.core.convert.support;
final class StringToInteger implements Converter<String, Integer> {
public Integer convert(String source) {
return Integer.valueOf(source);
}
}
用ConverterFactory
当您需要集中整个类层次结构的转换逻辑时
(例如,在从对象转换时),可以实现 ,如以下示例所示:String
Enum
ConverterFactory
package org.springframework.core.convert.converter;
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
参数化 S 为要从中转换的类型,将 R 参数化为定义的基类型
可以转换为的类范围。然后实现,
其中 T 是 R 的子类。getConverter(Class<T>)
以以下为例: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());
}
}
}
用GenericConverter
当您需要复杂的实现时,请考虑使用该接口。具有更灵活但类型较少的签名
比 ,a 支持在多个源和
目标类型。此外,a 提供源和目标字段
在实现转换逻辑时可以使用的上下文。这样的上下文让
类型转换由字段注释或在
字段签名。以下列表显示了 的接口定义:Converter
GenericConverter
Converter
GenericConverter
GenericConverter
GenericConverter
package org.springframework.core.convert.converter;
public interface GenericConverter {
public Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
要实现 ,请返回支持的
源→目标类型对。然后实现以包含您的转换逻辑。源提供
访问保存要转换的值的源字段。目标提供对要设置转换值的目标字段的访问。GenericConverter
getConvertibleTypes()
convert(Object, TypeDescriptor,
TypeDescriptor)
TypeDescriptor
TypeDescriptor
一个很好的例子是在 Java 数组之间转换的转换器
和一个集合。这样的内省是声明的领域
用于解析集合的元素类型的目标集合类型。这让每个
源数组中的元素转换为集合元素类型,然后再
在目标字段上设置集合。GenericConverter
ArrayToCollectionConverter
因为是更复杂的SPI接口,所以应该使用
它只在你需要的时候。偏爱或基本类型
转换需求。GenericConverter Converter ConverterFactory |
用ConditionalGenericConverter
有时,您希望仅当特定条件成立时才运行。为
例如,您可能希望仅在存在特定批注时运行
,或者您可能希望运行 Only If 特定方法
(例如方法)在目标类上定义。 是 和 接口的并集,可用于定义此类自定义匹配条件:Converter
Converter
Converter
static valueOf
ConditionalGenericConverter
GenericConverter
ConditionalConverter
public interface ConditionalConverter {
boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}
public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
}
a 的一个很好的例子是转换
在持久实体标识符和实体引用之间。仅当目标实体类型声明静态查找器方法(例如,)。您可以在 的实现中执行这样的查找器方法检查。ConditionalGenericConverter
IdToEntityConverter
IdToEntityConverter
findAccount(Long)
matches(TypeDescriptor, TypeDescriptor)
The APIConversionService
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);
}
大多数实现还实现了 ,其中
提供用于注册转换器的 SPI。在内部,实现委托给其注册的转换器来执行类型转换逻辑。ConversionService
ConverterRegistry
ConversionService
该软件包中提供了一个健壮的实现。 通用实现是否适用于
在大多数环境中使用。 提供便利的工厂
创建通用配置。ConversionService
core.convert.support
GenericConversionService
ConversionServiceFactory
ConversionService
配置ConversionService
A 是一个无状态对象,旨在在应用程序中实例化
启动,然后在多个线程之间共享。在 Spring 应用程序中,通常
为每个 Spring 容器(或 )配置一个实例。
Spring 会拾取它并在类型时使用它
转换需要由框架执行。您也可以将其注入到任何 Bean 中并直接调用它。ConversionService
ConversionService
ApplicationContext
ConversionService
ConversionService
如果 no 在 Spring 中注册,则基于原始 -
使用系统。ConversionService PropertyEditor |
要向 Spring 注册默认值,请添加以下 bean 定义
具有 :ConversionService
id
conversionService
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean"/>
默认值可以在字符串、数字、枚举、集合、
地图和其他常见类型。要补充或覆盖默认转换器,请使用
自己的自定义转换器,设置属性。属性值可以实现
任何 、 或 接口。ConversionService
converters
Converter
ConverterFactory
GenericConverter
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="example.MyCustomConverter"/>
</set>
</property>
</bean>
在 Spring MVC 应用程序中使用 a 也很常见。请参阅 Spring MVC 章节中的转换和格式设置。ConversionService
在某些情况下,您可能希望在转换过程中应用格式。有关使用 的详细信息,请参见 FormatterRegistry
SPI。FormattingConversionServiceFactoryBean
以编程方式使用ConversionService
要以编程方式使用实例,您可以注入对
就像你对任何其他豆子一样。以下示例演示如何执行此操作:ConversionService
-
Java
-
Kotlin
@Service
public class MyService {
private final ConversionService conversionService;
public MyService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public void doIt() {
this.conversionService.convert(...)
}
}
@Service
class MyService(private val conversionService: ConversionService) {
fun doIt() {
conversionService.convert(...)
}
}
对于大多数用例,您可以使用指定 的方法,但它
不适用于更复杂的类型,例如参数化元素的集合。
例如,如果要以编程方式将 of 转换为 of ,
您需要提供源和目标类型的正式定义。convert
targetType
List
Integer
List
String
幸运的是,提供了各种选项来使操作变得简单,
如以下示例所示:TypeDescriptor
-
Java
-
Kotlin
DefaultConversionService cs = new DefaultConversionService();
List<Integer> input = ...
cs.convert(input,
TypeDescriptor.forObject(input), // List<Integer> type descriptor
TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class)));
val cs = DefaultConversionService()
val input: List<Integer> = ...
cs.convert(input,
TypeDescriptor.forObject(input), // List<Integer> type descriptor
TypeDescriptor.collection(List::class.java, TypeDescriptor.valueOf(String::class.java)))
请注意,自动注册的转换器是
适用于大多数环境。这包括集合转换器、标量
转换器和基本转换器。您可以注册相同的转换器
通过对类使用 static 方法。DefaultConversionService
Object
String
ConverterRegistry
addDefaultConverters
DefaultConversionService
值类型的转换器重用于数组和集合,因此有
无需创建特定的转换器来从 的 的 转换为 的 ,前提是标准集合处理是合适的。Collection
S
Collection
T