• Spring源码分析之ConversionService


    前言

    ConversionService表示类型转换服务,如将字符串转换为Long,字符串转换为日期等。在处理属性和创建Bean对象等很多场景都会使用到。

    ConversionService

    相关类图如下

    默认实现为DefaultConversionService,默认增加了很多类型转换器,如字符串转为集合。

    import org.springframework.core.convert.ConversionService;
    import org.springframework.core.convert.support.DefaultConversionService;
    
    public class Client {
    
      public static void main(String[] args) {
        ConversionService sharedInstance = DefaultConversionService.getSharedInstance();
        System.out.println(sharedInstance);//查看所有Converter
        System.out.println(sharedInstance.canConvert(String.class, Integer.class));
        System.out.println(sharedInstance.convert("123", Integer.class));
      }
    
    }
    

    DefaultConversionService使用双重锁判断来实现单例,不仅实现了ConversionService接口(类型转换),,也实现了ConverterRegistry接口(注册表,可以增加转换器)。

    配置自定义类型转换器

    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    import org.springframework.core.convert.converter.Converter;
    import org.springframework.core.convert.support.DefaultConversionService;
    
    public class TestCustomConverter {
    
      public static void main(String[] args) {
        DefaultConversionService sharedInstance = (DefaultConversionService) DefaultConversionService
            .getSharedInstance();
        sharedInstance.addConverter(new StringToUserConverter());
        User user = sharedInstance.convert("lisi", User.class);
        System.out.println(user);//TestCustomConverter.User(name=lisi)
      }
    
    
      @Getter
      @Setter
      @ToString
      @AllArgsConstructor
      @NoArgsConstructor
      public static class User {
    
        private String name;
      }
    
      public static class StringToUserConverter implements Converter<String, User> {
    
        @Override
        public User convert(String source) {
          return new User(source);
        }
      }
    
    }
    

    自定义类型转换器需要实现Converter接口,第一个泛型表示源类型,第二个表示目标类型。

    Spring中配置ConversionService

    import java.util.HashSet;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.support.ConversionServiceFactoryBean;
    
    @Configuration
    public class BeanConfig {
    
      @Bean("conversionService")
      public ConversionServiceFactoryBean conversionServiceFactoryBean() {
        ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
        //可以在这里添加自定义类型转换器
        factoryBean.setConverters(new HashSet<>());
        return factoryBean;
      }
    }
    

    使用JavaConfig的方式来配置Bean,ConversionServiceFactoryBean底层实现也是DefaultConversionService。

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.core.convert.ConversionService;
    
    public class TestConversionServiceConfig {
    
      public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
            BeanConfig.class);
        ConversionService conversionService = context.getBeanFactory().getConversionService();
        System.out.println(conversionService.convert("123", Integer.class));//123
      }
    }
    

    注意配置的ConversionServiceFactoryBean的Bean名称必须为conversionService,这是因为BeanFactory会查找类型为ConversionService且名称为conversionService的Bean。

    SpringBoot配置自定义Converter

    SpringBoot会自动配置ConversionService对象,实现类为ApplicationConversionService(包含更多的类型转换器)。

    import org.springframework.context.annotation.Configuration;
    import org.springframework.format.FormatterRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
      @Override
      public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToUserConverter());
      }
    }
    

    SpringBoot也会将所有实现Converter接口的Bean添加到ConverterRegistry。

  • 相关阅读:
    sql行列互换
    转: 在hibernate中查询使用list,map定制返回类型
    拦截器和过滤器的区
    hibernate 实体对象的三种状态以及转换关系。
    如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理的?
    Hibernate常见优化策略
    Hibernate的一级缓存、二级缓存和查询缓存。
    关于java Collections.sort 排序
    常用颜色,正则表达式工具
    java正则表达式
  • 原文地址:https://www.cnblogs.com/strongmore/p/16220800.html
Copyright © 2020-2023  润新知