4. 上新了Spring,全新一代类型转换机制(上)

简介: 4. 上新了Spring,全新一代类型转换机制(上)

✍前言


你好,我是YourBatman。


上篇文章 介绍完了Spring类型转换早期使用的PropertyEditor详细介绍,关于PropertyEditor现存的资料其实还蛮少的,希望这几篇文章能弥补这块空白,贡献一份微薄之力。


如果你也吐槽过PropertyEditor不好用,那么本文将对会有帮助。Spring自3.0版本开始自建了一套全新类型转换接口,这就是本文的主要内容,接下来逐步展开。


说明:Spring自3.0后笑傲群雄,进入大一统。Java从此步入Spring的时代


版本约定


  • Spring Framework:5.3.1
  • Spring Boot:2.4.0

image.png



✍正文


在了解新一代的转换接口之前,先思考一个问题:Spring为何要自己造一套轮子呢? 一向秉承不重复造轮子原则的Spring,不是迫不得已的话是不会去动他人奶酪的,毕竟互利共生才能长久。类型转换,作为Spring框架的基石,扮演着异常重要的角色,因此对其可扩展性、可维护性、高效性均有很高要求。


基于此,我们先来了解下PropertyEditor设计上到底有哪些缺陷/不足(不能满足现代化需求),让Spring“被迫”走上了自建道路。


PropertyEditor设计缺陷


前提说明:本文指出它的设计缺陷,只讨论把它当做类型转换器在转换场景下存在的一些缺陷。


  1. 职责不单一:该接口有非常多的方法,但只用到2个而已
  2. 类型不安全:setValue()方法入参是Object,getValue()返回值是Object,依赖于约定好的类型强转,不安全
  3. 线程不安全:依赖于setValue()后getValue(),实例是线程不安全的
  4. 语义不清晰:从语义上根本不能知道它是用于类型转换的组件
  5. 只能用于String类型:它只能进行String <-> 其它类型的转换,而非更灵活的Object <-> Object


PropertyEditor存在这五宗“罪”,让Spring决定自己设计一套全新API用于专门服务于类型转换,这就是本文标题所述:新一代类型转换Converter、ConverterFactory、GenericConverter。


关于PropertyEditor在Spring中的详情介绍,请参见文章:3. 搞定收工,PropertyEditor就到这


新一代类型转换


为了解决PropertyEditor作为类型转换方式的设计缺陷,Spring 3.0版本重新设计了一套类型转换接口,有3个核心接口:


  1. Converter<S, T>:Source -> Target类型转换接口,适用于1:1转换
  2. ConverterFactory<S, R>:Source -> R类型转换接口,适用于1:N转换
  3. GenericConverter:更为通用的类型转换接口,适用于N:N转换

   1.注意:就它没有泛型约束,因为是通用


另外,还有一个条件接口ConditionalConverter,可跟上面3个接口搭配组合使用,提供前置条件判断验证。


这套接口,解决了PropertyEditor做类型转换存在的所有缺陷,且具有非常高的灵活性和可扩展性。下面进入详细了解。


Converter


将源类型S转换为目标类型T。


@FunctionalInterface
public interface Converter<S, T> {
  T convert(S source);
}


它是个函数式接口,接口定义非常简单。适合1:1转换场景:可以将任意类型 转换为 任意类型。它的实现类非常多,部分截图如下:


image.png


值得注意的是:几乎所有实现类的访问权限都是default/private,只有少数几个是public公开的,下面我用代码示例来“近距离”感受一下。


代码示例


/**
 * Converter:1:1
 */
@Test
public void test() {
    System.out.println("----------------StringToBooleanConverter---------------");
    Converter<String, Boolean> converter = new StringToBooleanConverter();
    // trueValues.add("true");
    // trueValues.add("on");
    // trueValues.add("yes");
    // trueValues.add("1");
    System.out.println(converter.convert("true"));
    System.out.println(converter.convert("1"));
    // falseValues.add("false");
    // falseValues.add("off");
    // falseValues.add("no");
    // falseValues.add("0");
    System.out.println(converter.convert("FalSe"));
    System.out.println(converter.convert("off"));
    // 注意:空串返回的是null
    System.out.println(converter.convert(""));
    System.out.println("----------------StringToCharsetConverter---------------");
    Converter<String, Charset> converter2 = new StringToCharsetConverter();
    // 中间横杠非必须,但强烈建议写上   不区分大小写
    System.out.println(converter2.convert("uTf-8"));
    System.out.println(converter2.convert("utF8"));
}


运行程序,正常输出:

----------------StringToBooleanConverter---------------
true
true
false
false
null
----------------StringToCharsetConverter---------------
UTF-8
UTF-8


说明:StringToBooleanConverter/StringToCharsetConverter访问权限都是default,外部不可直接使用。此处为了做示例用到一个小技巧 -> 将Demo的报名调整为和转换器的一样,这样就可以直接访问。


关注点:true/on/yes/1都能被正确转换为true的,且对于英文字母来说一般都不区分大小写,增加了容错性(包括Charset的转换)。


不足


Converter用于解决1:1的任意类型转换,因此它必然存在一个不足:解决1:N转换问题需要写N遍,造成重复冗余代码。


譬如:输入是字符串,它可以转为任意数字类型,包括byte、short、int、long、double等等,如果用Converter来转换的话每个类型都得写个转换器,想想都麻烦有木有。


Spring早早就考虑到了该场景,提供了相应的接口来处理,它就是ConverterFactory<S, R>。




相关文章
|
7月前
|
存储 安全 Java
事件的力量:探索Spring框架中的事件处理机制
事件的力量:探索Spring框架中的事件处理机制
75 0
|
7月前
|
设计模式 前端开发 Java
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究SpringMVC的核心原理和运作机制(总体框架原理篇)
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究SpringMVC的核心原理和运作机制(总体框架原理篇)
71 0
|
7月前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
15天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
45 2
|
7月前
|
Java 测试技术 开发者
Spring IoC容器通过依赖注入机制实现控制反转
【4月更文挑战第30天】Spring IoC容器通过依赖注入机制实现控制反转
64 0
|
4月前
|
Java 开发工具 Spring
Spring的Factories机制介绍
Spring的Factories机制介绍
79 1
|
5月前
|
安全 Java API
构建基于Spring Boot的REST API安全机制
构建基于Spring Boot的REST API安全机制
|
6月前
|
Java 应用服务中间件 Spring
解析Spring Boot自动装配的原理与机制
解析Spring Boot自动装配的原理与机制
118 4
|
5月前
|
Java Spring
解析Spring Boot中的事务管理机制
解析Spring Boot中的事务管理机制
|
5月前
|
缓存 安全 Java
Spring Boot中的自动配置机制详解
Spring Boot中的自动配置机制详解