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

相关推荐
洛_尘1 分钟前
Java EE进阶:Linux的基本使用
java·java-ee
宸津-代码粉碎机3 分钟前
Spring Boot 4.0虚拟线程实战调优技巧,最大化发挥并发优势
java·人工智能·spring boot·后端·python
MaCa .BaKa5 分钟前
47-心里健康咨询平台/心理咨询系统
java·spring boot·mysql·tomcat·maven·intellij-idea·个人开发
木子欢儿24 分钟前
Docker Hub 镜像发布指南
java·spring cloud·docker·容器·eureka
头疼的程序员30 分钟前
计算机网络:自顶向下方法(第七版)第八章 学习分享(三)
网络·学习·计算机网络
Devin~Y35 分钟前
高并发电商与AI智能客服场景下的Java面试实战:从Spring Boot到RAG与向量数据库落地
java·spring boot·redis·elasticsearch·spring cloud·kafka·rag
蜡台39 分钟前
IDEA 一些 使用配置和插件
java·ide·intellij-idea
磊 子1 小时前
redis详解2
java·spring boot·redis
白露与泡影1 小时前
Java面试题库及答案解析(2026版)
java·开发语言·面试
_李小白1 小时前
【OSG学习笔记】Day 37: NodeVisitor(顶点访问器)
笔记·学习