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 框架中用于类型转换的强大工具,它提供了灵活且可扩展的转换机制,适用于各种需要类型转换的场景。

相关推荐
让学习成为一种生活方式10 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
Mephisto.java10 分钟前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
晨曦_子画16 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
南宫生39 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
Heavydrink1 小时前
HTTP动词与状态码
java
ktkiko111 小时前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
神里大人1 小时前
idea、pycharm等软件的文件名红色怎么变绿色
java·pycharm·intellij-idea
小冉在学习2 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论
武子康2 小时前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘