ConversionService学习

简介

ConversionService 是 Spring 框架中的一个接口,它提供了一种机制来执行类型之间的转换。ConversionService 允许开发者定义自己的转换逻辑,并注册到服务中,从而可以在运行时动态地转换对象。这种机制在数据绑定、服务层方法参数转换以及任何需要类型转换的场景中都非常有用。

ConversionService 接口定义了一个简单的方法 convert(Object source, Class<?> targetType),它尝试将源对象转换为目标类型的实例。如果转换不可能或未定义,该方法通常会抛出一个异常。

Spring 提供了 ConversionService 的多个实现,其中 DefaultConversionService 是最常用的一个。DefaultConversionService 提供了对许多内置类型转换的支持,包括基本数据类型、字符串、集合和数组之间的转换等。此外,开发者还可以通过实现 Converter 或 ConditionalConverter 接口,并将自定义的转换器注册到 ConversionService 中,来扩展转换功能。

源码

java 复制代码
public interface ConversionService {

	/**
	 * Return {@code true} if objects of {@code sourceType} can be converted to the {@code targetType}.
	 * <p>If this method returns {@code true}, it means {@link #convert(Object, Class)} is capable
	 * of converting an instance of {@code sourceType} to {@code targetType}.
	 * <p>Special note on collections, arrays, and maps types:
	 * For conversion between collection, array, and map types, this method will return {@code true}
	 * even though a convert invocation may still generate a {@link ConversionException} if the
	 * underlying elements are not convertible. Callers are expected to handle this exceptional case
	 * when working with collections and maps.
	 * @param sourceType the source type to convert from (may be {@code null} if source is {@code null})
	 * @param targetType the target type to convert to (required)
	 * @return {@code true} if a conversion can be performed, {@code false} if not
	 * @throws IllegalArgumentException if {@code targetType} is {@code null}
	 * 是否可以从sourceType转换为targetType
	 */
	boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);

	/**
	 * Return {@code true} if objects of {@code sourceType} can be converted to the {@code targetType}.
	 * The TypeDescriptors provide additional context about the source and target locations
	 * where conversion would occur, often object fields or property locations.
	 * <p>If this method returns {@code true}, it means {@link #convert(Object, TypeDescriptor, TypeDescriptor)}
	 * is capable of converting an instance of {@code sourceType} to {@code targetType}.
	 * <p>Special note on collections, arrays, and maps types:
	 * For conversion between collection, array, and map types, this method will return {@code true}
	 * even though a convert invocation may still generate a {@link ConversionException} if the
	 * underlying elements are not convertible. Callers are expected to handle this exceptional case
	 * when working with collections and maps.
	 * @param sourceType context about the source type to convert from
	 * (may be {@code null} if source is {@code null})
	 * @param targetType context about the target type to convert to (required)
	 * @return {@code true} if a conversion can be performed between the source and target types,
	 * {@code false} if not
	 * @throws IllegalArgumentException if {@code targetType} is {@code null}
	 * 同上
	 */
	boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);

	/**
	 * Convert the given {@code source} to the specified {@code targetType}.
	 * @param source the source object to convert (may be {@code null})
	 * @param targetType the target type to convert to (required)
	 * @return the converted object, an instance of targetType
	 * @throws ConversionException if a conversion exception occurred
	 * @throws IllegalArgumentException if targetType is {@code null}
	 * 将source转换为targetType
	 */
	@Nullable
	<T> T convert(@Nullable Object source, Class<T> targetType);

	/**
	 * Convert the given {@code source} to the specified {@code targetType}.
	 * The TypeDescriptors provide additional context about the source and target locations
	 * where conversion will occur, often object fields or property locations.
	 * @param source the source object to convert (may be {@code null})
	 * @param sourceType context about the source type to convert from
	 * (may be {@code null} if source is {@code null})
	 * @param targetType context about the target type to convert to (required)
	 * @return the converted object, an instance of {@link TypeDescriptor#getObjectType() targetType}
	 * @throws ConversionException if a conversion exception occurred
	 * @throws IllegalArgumentException if targetType is {@code null},
	 * or {@code sourceType} is {@code null} but source is not {@code null}
	 * 同上
	 */
	@Nullable
	Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);

}

示例

java 复制代码
import org.springframework.context.support.ConversionServiceFactoryBean;  
import org.springframework.format.support.DefaultFormattingConversionService;  
  
public class ConversionServiceExample {  
  
    public static void main(String[] args) {  
        // 创建一个 ConversionService 实例  
        ConversionService conversionService = new DefaultFormattingConversionService();  
  
        // 注册自定义转换器  
        conversionService.addConverter(new MyCustomConverter());  
  
        // 执行类型转换  
        String sourceValue = "123";  
        Integer targetValue = conversionService.convert(sourceValue, Integer.class);  
  
        System.out.println(targetValue); // 输出:123  
    }  
  
    // 自定义转换器  
    static class MyCustomConverter implements Converter<String, Integer> {  
        @Override  
        public Integer convert(String source) {  
            // 自定义转换逻辑  
            return Integer.parseInt(source);  
        }  
    }  
}

在这个例子中,我们首先创建了一个 DefaultFormattingConversionService 实例。然后,我们注册了一个自定义的转换器 MyCustomConverter,它将字符串转换为整数。最后,我们使用 ConversionService 的 convert 方法将字符串 "123" 转换为 Integer 对象。

除了 Converter,Spring 还提供了 GenericConverter 接口,它允许更复杂的转换逻辑,包括处理源类型和目标类型都是泛型参数的情况。

ConversionService 在 Spring MVC 中也扮演着重要角色,它用于将请求参数绑定到控制器方法的参数上时进行类型转换。通过配置 Spring MVC 的 FormattingConversionService 或自定义 ConversionService,你可以控制请求参数的转换行为。

总之,ConversionService 是 Spring 框架中用于类型转换的强大工具,它提供了灵活且可扩展的转换机制,适用于各种需要类型转换的场景。

相关推荐
随便取个六字几秒前
GIT操作 学习
git·学习
chuanauc3 分钟前
Kubernets K8s 学习
java·学习·kubernetes
小张是铁粉7 分钟前
docker学习二天之镜像操作与容器操作
学习·docker·容器
一头生产的驴19 分钟前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao25 分钟前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc78729 分钟前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
小张是铁粉32 分钟前
oracle的内存架构学习
数据库·学习·oracle·架构
HERR_QQ43 分钟前
【unify】unify的微信小程序开发学习 (to be continued)
学习·微信小程序·小程序
YuTaoShao3 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张33 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端