微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐