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

相关推荐
花间相见2 分钟前
【JAVA基础09】—— 赋值与三元运算符:从基础到实操的避坑指南
java·开发语言·python
ywlovecjy5 分钟前
windows配置永久路由
java
草莓熊Lotso7 分钟前
Linux 进程间通信之命名管道(FIFO):跨进程通信的实用方案
android·java·linux·运维·服务器·数据库·c++
小江的记录本9 分钟前
【AOP】AOP-面向切面编程 (系统性知识体系全解)
java·前端·后端·python·网络协议·青少年编程·代理模式
XiaoLeisj13 分钟前
Android 文件与数据存储实战:SharedPreferences、SQLite 与 Room 的渐进式实现
android·java·数据库·ui·sqlite·room·sp
MegaDataFlowers13 分钟前
认识O(NlogN)的排序
java·开发语言·排序算法
头疼的程序员17 分钟前
计算机网络:自顶向下方法(第七版)第四章 学习分享(一)
网络·学习·计算机网络
w1225h22 分钟前
【SpringBoot】Spring Boot 项目的打包配置
java·spring boot·后端
李少兄22 分钟前
解析 IntelliJ IDEA “Immutable object is modified”警告
java·ide·intellij-idea
客卿12323 分钟前
二叉树的层序遍历--思路===bfs的应用,以及java中队列的方法实操
java·算法·宽度优先