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

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

ConverterFactory


从名称上看它代表一个转换工厂:可以将对象S转换为R的所有子类型,从而形成1:N的关系。


该接口描述为xxxFactory是非常合适的,很好的表达了1:N的关系


public interface ConverterFactory<S, R> {
  <T extends R> Converter<S, T> getConverter(Class<T> targetType);
}


它同样也是个函数式接口。该接口的实现类并不多,Spring Framework共提供了5个内建实现(访问权限全部为default):


image.png


以StringToNumberConverterFactory为例看看实现的套路:


final class StringToNumberConverterFactory implements ConverterFactory<String, Number> {
  @Override
  public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) {
    return new StringToNumber<T>(targetType);
  }
  // 私有内部类:实现Converter接口。用泛型边界约束一类类型
  private static final class StringToNumber<T extends Number> implements Converter<String, T> {
    private final Class<T> targetType;
    public StringToNumber(Class<T> targetType) {
      this.targetType = targetType;
    }
    @Override
    public T convert(String source) {
      if (source.isEmpty()) {
        return null;
      }
      return NumberUtils.parseNumber(source, this.targetType);
    }
  }
}


由点知面,ConverterFactory作为Converter的工厂,对Converter进行包装,从而达到屏蔽内部实现的目的,对使用者友好,这不正是工厂模式的优点么,符合xxxFactory的语义。但你需要清除的是,工厂内部实现其实也是通过众多if else之类的去完成的,本质上并无差异。


代码示例


/**
 * ConverterFactory:1:N
 */
@Test
public void test2() {
    System.out.println("----------------StringToNumberConverterFactory---------------");
    ConverterFactory<String, Number> converterFactory = new StringToNumberConverterFactory();
    // 注意:这里不能写基本数据类型。如int.class将抛错
    System.out.println(converterFactory.getConverter(Integer.class).convert("1").getClass());
    System.out.println(converterFactory.getConverter(Double.class).convert("1.1").getClass());
    System.out.println(converterFactory.getConverter(Byte.class).convert("0x11").getClass());
}


运行程序,正常输出:


----------------StringToNumberConverterFactory---------------
class java.lang.Integer
class java.lang.Double
class java.lang.Byte


关注点:数字类型的字符串,是可以被转换为任意Java中的数字类型的,String(1) -> Number(N)。这便就是ConverterFactory的功劳,它能处理这一类转换问题。


不足


既然有了1:1、1:N,自然就有N:N。比如集合转换、数组转换、Map到Map的转换等等,这些N:N的场景,就需要借助下一个接口GenericConverter来实现。


GenericConverter


它是一个通用的转换接口,用于在两个或多个类型之间进行转换。相较于前两个,这是最灵活的SPI转换器接口,但也是最复杂的。


public interface GenericConverter {
  Set<ConvertiblePair> getConvertibleTypes();
  Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
  // 普通POJO
  final class ConvertiblePair {
    private final Class<?> sourceType;
    private final Class<?> targetType;
  }
}


该接口并非函数式接口,虽然方法不多但稍显复杂。现对出现的几个类型做简单介绍:


  • ConvertiblePair:维护sourceType和targetType的POJO
  • getConvertibleTypes()方法返回此Pair的Set集合。由此也能看出该转换器是可以支持N:N的(大多数情况下只写一对值而已,也有写多对的)
  • TypeDescriptor:类型描述。该类专用于Spring的类型转换场景,用于描述from or to的类型
  • 比单独的Type类型强大,内部借助了ResolvableType来解决泛型议题


GenericConverter的内置实现也比较多,部分截图如下:


image.png


ConditionalGenericConverter是GenericConverter和条件接口ConditionalConverter的组合,作用是在执行GenericConverter转换时增加一个前置条件判断方法。


image.png


说明:分割线下面的4个转换器比较特殊,字面上不好理解其实际作用,比较“高级”。它们如果能被运用在日常工作中可以事半功弎,因此放在在下篇文章专门给你介绍



相关文章
|
8月前
|
存储 安全 Java
事件的力量:探索Spring框架中的事件处理机制
事件的力量:探索Spring框架中的事件处理机制
80 0
|
8月前
|
设计模式 前端开发 Java
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究SpringMVC的核心原理和运作机制(总体框架原理篇)
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究SpringMVC的核心原理和运作机制(总体框架原理篇)
79 0
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
87 2
|
17天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
67 14
|
1月前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
55 4
|
2月前
|
Java 开发者 Spring
深入解析:Spring AOP的底层实现机制
在现代软件开发中,Spring框架的AOP(面向切面编程)功能因其能够有效分离横切关注点(如日志记录、事务管理等)而备受青睐。本文将深入探讨Spring AOP的底层原理,揭示其如何通过动态代理技术实现方法的增强。
76 8
|
8月前
|
Java 测试技术 开发者
Spring IoC容器通过依赖注入机制实现控制反转
【4月更文挑战第30天】Spring IoC容器通过依赖注入机制实现控制反转
70 0
|
5月前
|
Java 开发工具 Spring
Spring的Factories机制介绍
Spring的Factories机制介绍
111 1
|
6月前
|
安全 Java API
构建基于Spring Boot的REST API安全机制
构建基于Spring Boot的REST API安全机制
|
7月前
|
Java 应用服务中间件 Spring
解析Spring Boot自动装配的原理与机制
解析Spring Boot自动装配的原理与机制
133 4