ConversionService表示类型转换服务,如将字符串转换为Long,字符串转换为日期等。在处理属性和创建Bean对象等很多场景都会使用到。
相关类图如下
默认实现为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接口,第一个泛型表示源类型,第二个表示目标类型。
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会自动配置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。