Spring 6【数据绑定之类型转换(Type Conversion)】(十一)-全面详解(学习总结---从入门到深化)

news2024/11/16 3:30:17

 

目录

数据绑定之类型转换(Type Conversion)


数据绑定之类型转换(Type Conversion)

1.PropertyEditor

在Spring框架3.0之前并没有提供类型转换器,而是使用JDK原生的java.beans.PropertyEditor进行类型转换(提供了PropertyEditor接口的几个实现类)。从3.0版本之后Spring框架提供了对PropertyEditor 的替代。虽然从3.0出现了替代品,但是在目前的Spring Framework 6版本中PropertyEditor依然发挥着余热。所以学习好PropertyEditor也是非常有必要的。我们先来看看JDK原生的PropertyEditor怎么用。

PropertyEditor如果直译叫做“属性编辑器”,但是我们应该叫它“类型转换器”更加贴合。老Java程序员对它比较熟悉,因为它更多的使用场景是结合在AWT中的内容一起使用(Java的AWT目前已经几乎不使用 了)。作用是用户通过GUI输入一个字符串的值,然后通过PropertyEditor进行类型转换,转换为我们想要的类型。 

接口中提供的方法

public interface PropertyEditor {
     void setValue(Object value);
     Object getValue();
     boolean isPaintable();
     void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box);
     String getJavaInitializationString();
     String getAsText();
     void setAsText(String text) throws java.lang.IllegalArgumentException;
     String[] getTags();
     java.awt.Component getCustomEditor();
     boolean supportsCustomEditor();
     void addPropertyChangeListener(PropertyChangeListener listener);
     void removePropertyChangeListener(PropertyChangeListener listener);
}

 既然目前Java中AWT已经不使用了,为什么说目前Spring6框架还在使用PropertyEditor的扩展呢?其实也很简单:Java GUI中用户在图形界面输入的内容是字符串,需要进行类型转换为Java支持的类型。而 Spring框架支持XML配置文件,XML配置文件里面内容也都是字符串类型,也需要转换为Bean中属性对应的类型,所以原理是想通的。这也是Spring框架为什么使用PropertyEditor。

2003年时Spring刚出现,本着不重复发明轮子,示好Sun公司,所以很多Spring早期的底层机制都是基于JDK的。后面Spring另起炉灶,开始自己出了一系列替代,是因为Spring强大了。 而且在2003年的时候,Java AWT并没有退出历史舞台。但Spring 在实现PropertyEditor也就是简单重写了下getAsText();和setAsText(String text)

 PropertyEditor提供了实现类PropertyEditorSupport(非线程安全),当我们想要使用 PropertyEditor,或者对JDK提供的规范扩充都可以继承这个类进行重写(Spring框架对 PropertyEditor扩展就是继承这个类)。

在JDK中SUN规范所有对PropertyEditor的实现都放在了com.sun.beans.editors中。

以IntegerEditor为例。就是把字符串转为数字,转换过程可以实现进制数。

public class IntegerEditor extends NumberEditor {
    public void setAsText(String text) throws IllegalArgumentException {
        setValue((text == null) ? null : Integer.decode(text));
    }
}

 Integer的decode方法

public static Integer decode(String nm) throws NumberFormatException {
    int radix = 10;
    int index = 0;
    boolean negative = false;
    Integer result;

    if (nm.isEmpty())
         throw new NumberFormatException("Zero length string");
    char firstChar = nm.charAt(0);

    if (firstChar == '-') {
         negative = true;
         index++;
      } else if (firstChar == '+')
           index++;
  
    if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
         index += 2;
         radix = 16;
      }
      else if (nm.startsWith("#", index)) {
         index ++;
         radix = 16;
      }
      else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
         index ++;
         radix = 8;
      }

    if (nm.startsWith("-", index) || nm.startsWith("+", index)) throw new NumberFormatException("Sign character in wrong position");
       try {
             result = Integer.valueOf(nm.substring(index), radix);
             result = negative ? Integer.valueOf(-result.intValue()) : result;
          } catch (NumberFormatException e) {
               String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index);
            result = Integer.valueOf(constant, radix);
        }
     return result;
}

除了IntegerEditor以外,其他的PropertyEditor都是从String类型,转换为其他类型,所以功能明显不足。

2.Spring框架中类型转换器

从Spring Framework 3.0开始提供了更加强大的内置转换器,分别是:Converter、 ConverterFactory、GenericConverter 三个接口及实现类,但是这些实现类绝大多数都是default修 饰,无法跨包访问。

这三个接口的功能要比PropertyEditor更加强大。可以实现某个类型向另外一个类型转换,不再局限于 String向其他类型转换。

但是Spring框架到目前的Spring Framework 6一直都对两种方式进行支持。这也是Spring框架的特点, 解耦和原生API方式,让我们开发者自己选(为了让开发者更倾向使用解耦方式,一般解耦方式使用起来 都比原生简单)。

Spring框架类型转换经常发生的,只是这个事情由Spring框架完成,程序员不深入底层时,只是知道有这个事情。如果深入了解Spring框架,就知道Spring在进行数据绑定时会帮助我们进行类型转换。

类型转换几个常见场景。

  • Xml文件配置的Bean属性都是字符串类型,而Bean属性类型确不仅仅是字符串。这时会用类型转 换。
  • @Value注解。properties文件中值都是字符串,获取后希望是某个类型。这时会用类型转换
  • Spring MVC接收请求参数。HTTP请求参数都是字符串,在我们接收时希望接收为其他类型, Spring框架在数据绑定时会进行类型转换。

2.1 Converter接口

Converter接口功能比较简单,就是把S类型值转换为T类型。Spring默认提供了很多实现类,都是一些简单数据类型到另一种简单数据类型的转换。

@FunctionalInterface
public interface Converter<S, T> {

/**
* 从S类型转换为T类型
*/
@Nullable
T convert(S source);

/**
* 从Spring 5.3版本出现的默认方法,允许转换后再次使用另一个转换器(after)进行转换后返回
*/
   default <U> Converter<S, U> andThen(Converter<? super T, ? extends U> after)
   {
         Assert.notNull(after, "'after' Converter must not be null");
         return (S s) -> {
              T initialResult = convert(s);
              return (initialResult != null ? after.convert(initialResult) : null);
         };
     }
}

里面提供了大量的实现了,但是这些类的访问权限修饰符都是default,意味着跨包无法访问。

2.2 ConverterFactory

用于把S类型转换为T类型,但是强制要求T的类型必须是R类型子类。具体是什么类型都行,只要是之类中一种就可以。因为接口泛型中R设置为转换后结果类型的父类,所以具体转后后的类型可能是R的子类 1,也可能是R的子类2,所以有人认为这数据1:N的转换方式。

public interface ConverterFactory<S, R> {
    /**
     * 从S类型值转换为T类型,其中T类型必须继承R类型。
     */
    <T extends R> Converter<S, T> getConverter(Class<T> targetType);
}

 2.3 GenericConverter

GenericConverter转换器主要实现N:N的转换。例如

这些接口的实现类因为大部分都是default修饰,意味着是Spring框架自己使用的,如果想要使用可以实 现接口进行自定义实现。

以String转Integer为例,简单使用一下转换器 

自定义转换器

@Component
public class MyConverter implements Converter<String,Integer> {
    @Override
    public Integer convert(String source) {
         return Integer.parseInt(source);
     }
  }

测试结果

// 简写方式,省略@ContextConfiguration
@SpringJUnitConfig(MyConverter.class)
public class ConverterTest {
     @Autowired
     MyConverter myConverter;
     
     @Test
     void test(){
         Integer result = myConverter.convert("123");
         System.out.println(result);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/806289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

指令调度(Instruction Scheduling)

指令调度&#xff08;Instruction Scheduling&#xff09; 指令调度的约束基本机器模型基本块调度全局调度 指令调度是为了提高指令级并行&#xff08;ILP&#xff09;&#xff0c;对于超长指令字&#xff08;VLIW, Very Long Instruction Word&#xff09;和多发射系统&#x…

Jvm的一些技巧

反编译字节码文件 找到对应的class文件所在的目录&#xff0c;使用javap -v -p 命令 查询运行中某个Java进程的Jvm参数 【案例】查询 MethodAreaDemo 这个类运行过程中&#xff0c;初始的元空间大小 MetaspaceSize jps 查询 Java 进程的进程ID ![在这里插入图片描述](https…

GRACE数据反演的新理解

一、问题提出 “重力恢复与气候实验”&#xff08;GRACE&#xff09;为监测地球系统内全球大尺度质量变化提供了一种新途径。自2002年3月发射以来&#xff0c;GRACE一直在生成时间变化的重力场模型&#xff0c;这些模型可用于量化与全球气候变化相关的地球系统不同组成部分内的…

【C++11】——类的新功能

目录 1. 默认成员函数 2. 类成员变量初始化 3. 强制生成默认函数的关键字default 4. 禁止生成默认函数的关键字delect 5. 继承和多态的final与override关键字 6. 测试案例 1. 默认成员函数 原来C类中&#xff08;C11之前&#xff09;&#xff0c;有6个默认成员函数&…

管理类联考——写作——素材篇——论证有效性分析——常见逻辑谬误

批判性思维常见逻辑谬误 有些错误出现在我们澄清或定义某个观点的时候&#xff0c;有些错误出现在我们收集证据或者用证据和理由支撑某个观点的时候&#xff0c;有些错误出现在我们尝试从证据得出结论的时候&#xff0c;有些错误甚至出现在我们评估他人的观点或者理由的时候。…

Drools用户手册翻译——第四章 Drools规则引擎(八)drools中的事实传播模式和议程评估过滤器

甩锅声明&#xff1a;本人英语一般&#xff0c;翻译只是为了做个笔记&#xff0c;所以有翻译错误的地方&#xff0c;错就错了&#xff0c;如果你想给我纠正&#xff0c;就给我留言&#xff0c;我会改过来&#xff0c;如果懒得理我&#xff0c;就直接划过即可。 drools中的事实…

微信小程序开发每日一写--5

按钮的使用和底层逻辑的实现&#xff08;暂未成功&#xff09; WXML&#xff1a; <button class"bth1"type"primary" >按钮</button>JS&#xff1a; // index.js // 获取应用实例 //const app getApp() Page({/*bthTapHandler(e){//按钮的…

C动态内存分配

&#x1f388;对比一般内存分配和动态内存分配 &#x1f308;一般内存分配 int val 20; char arr[10] {0};特点&#xff1a; ①大小是固定的&#xff0c;一旦分配好就无法改变&#xff08;数组必须指定大小后编译器才能分配空间&#xff09; ②分配的空间具体放置什么类型的…

ffmpeg批量分割视频解决视频前几秒黑屏的问题解决

echo 请输入视频地址&#xff1a; set /p fp echo 请输入开始时间&#xff1a; set /p st echo 请输入结束时间&#xff1a; set /p et echo 请输入分片时间&#xff1a; set /p sgt echo 注意&#xff1a;循环范围参数要空格。 for /l %%i in (%st%, %sgt%, %et%) do call :aa…

【Spring AOP学习】AOP的组成 SpringAOP的实现和实现原理

目录 一、认识SpringAOP 1、AOP是什么&#xff1f; 2、AOP的功能 3、AOP的组成&#xff08;重要&#xff09; 二、SpringAOP的实现 &#x1f337;1、添加Spring AOP框架支持 &#x1f337;2、定义切面和切点 &#x1f337; 3、定义通知 3.1 完成代码实现 3.2 具体通知…

目前可以实现用手机操作水质自动采样器吗

利用自动采样器进行水样采集可以说节省很大的人力物力&#xff0c;但是有时为了采到更具代表性的水样&#xff0c;我们需要对沟渠、深井、排污口等特殊场景进行采样。像这些狭小的空间领域采样就有点困难&#xff0c;对现场工作人员就带来了一些难题。所以也需要一款可以在井下…

HCIP——OSPF的防环机制

OSPF的防环机制 一、域间防环二、域内防环有向图转化1、有向图的画法2、示例&#xff1a; 三、SPF算法 OSPF将整个OSPF域划分为多个区域&#xff0c;区域内部通过拓扑信息计算路由&#xff0c;区域间传递路由信息&#xff0c;实现全网可达。OSPF防环机制主要是体现在域内防环和…

python3GUI--我的二维码生成工具By:PyQt5(附UI源码)

文章目录 一&#xff0e;前言二&#xff0e;展示1.主界面2.主界面-选择颜色&#xff08;动图&#xff09;3.主界面-选择样式&#xff08;动图&#xff09; 三&#xff0e;思路1.UI设计2.核心3.其他1.为什么调整了样式左侧二维码就跟着变化2.首次启动软件生成的文件哪里来的3.作…

华为8月8日将推出系统云翻新功能:P40/Mate 30系列首发

7月28日消息&#xff0c;7月28日消息&#xff0c;华为终端公司近日在微博上发布重要公告&#xff0c;宣布将于8月8日推出全新的系统云翻新功能。据悉&#xff0c;该功能将首次应用于华为 P40 系列手机和 Mate30 系列手机&#xff0c;为用户提供更便捷的手机数据备份和恢复体验。…

如何降低机场人员定位系统成本?哪种方案简单又好用?

一、方案简介 机场是一个室内空间巨大的人员聚集地差旅人员找不到出入口、卫生间、商铺为找检票口而误车等是很常见的现状。面对这些问题&#xff0c;机场信息数字化建设成为一种最为有效的解决方式&#xff01; 华安联大通过多技术融合实现室内外位置健全&#xff0c;推出一…

【机密计算-大厂有话说】微软 Azure

什么是机密计算&#xff1f; 机密计算是由机密计算联盟 (CCC) 定义的一个行业术语&#xff0c;CCC 是专注于定义并加速机密计算落地的基金会。 CCC 给机密计算的定义是&#xff1a;通过在基于硬件的可信执行环境 (TEE) 中执行计算来保护使用中的数据。 TEE 是是一个只能执行授权…

Jetbrains idea 代码关闭 注释自动渲染 导致换行不生效

方法1 关闭注释自动渲染 取消勾选 方法2 结尾使用 <br> 强制换行

【Python】logging模块笔记

目录 日志级别 四个组件 记录器 处理器 处理器 格式化器 格式 用法1&#xff1a;小项目可以采用编程的方法 用法2&#xff1a;建议采用配置文件的方式 用法3&#xff1a; 字典配置 日志级别 #默认的日志输出为warning # 使用baseConfig() 来指定日志输出级别 # 同时&#x…

每日一题——找到消失的数字

找到消失的数字 题目链接 思路 一个长度为n的数组中所有数据的范围在[1,n]内&#xff0c;题目要求我们找出在[1,n]范围内&#xff0c;但数组中没有出现的数字 如果可以使用额外空间&#xff0c;那这题就好办了。我们直接创建一个相同大小的数组&#xff0c;数组的每个位置代…

三. 多传感器标定方案(空间同步)--2

前面的内容&#xff1a; 一. 器件选型心得&#xff08;系统设计&#xff09;--1_goldqiu的博客-CSDN博客 一. 器件选型心得&#xff08;系统设计&#xff09;--2_goldqiu的博客-CSDN博客 二. 多传感器时间同步方案&#xff08;时序闭环&#xff09;--1 三. 多传感器标定方案…