Spring Boot 2.0 配置属性自定义转换的方法
引言
当我们通过@ConfigurationProperties注解实现配置bean的时候,如果默认的配置属性转换无法满足我们的需求的时候,我们可以根据自己的需求通过以下扩展方式对配置属性进行转换
PropertyEditorSupport实现
下面的例子是把属性中定义的字符串转换成Movie,并且把name的值大写
继承PropertyEditorSupport并且实现PropertyEditorRegistrar接口
packagecom.paderlol.spring.practice.properties.editor; importcom.paderlol.spring.practice.properties.pojo.Movie; importjava.beans.PropertyEditorSupport; importlombok.extern.slf4j.Slf4j; importorg.springframework.beans.PropertyEditorRegistrar; importorg.springframework.beans.PropertyEditorRegistry; /** *@authorpaderPropertyEditor在不同的包下面 */ @Slf4j publicclassCustomMovieEditorextendsPropertyEditorSupport implementsPropertyEditorRegistrar{ @Override publicStringgetAsText(){ Moviemovie=(Movie)getValue(); returnmovie==null?"":movie.getName(); } @Override publicvoidsetAsText(Stringtext)throwsIllegalArgumentException{ log.info("继承[PropertyEditorSupport]类,转换数据={}",text); String[]data=text.split("-"); Moviemovie=Movie.builder().name(data[0] .toUpperCase()).seat(Integer.parseInt(data[1])) .build(); setValue(movie); } @Override publicvoidregisterCustomEditors(PropertyEditorRegistryregistry){ registry.registerCustomEditor(Movie.class,this); } }
注册自定义的PropertyEditor
@Bean publicCustomEditorConfigurercustomEditorConfigurer(){ CustomEditorConfigurercustomEditorConfigurer=newCustomEditorConfigurer(); //有两种注册方式这是第一种 customEditorConfigurer.setPropertyEditorRegistrars( newPropertyEditorRegistrar[]{newCustomMovieEditor()}); //第二种 Map,Class>maps=newHashMap<>(); maps.put(Movie.class,CustomMovieEditor.class); returncustomEditorConfigurer; }
Converter接口+@ConfigurationPropertiesBinding注解
//注意 @Component @ConfigurationPropertiesBinding publicclassStringToPersonConverterimplementsConverter{ @Override publicPersonconvert(Stringfrom){ log.info("使用[Converter]接口,转换数据={}",from); String[]data=from.split(","); returnPerson.builder().name(data[0]).age(Integer.parseInt(data[1])).build(); } }
总结
- 以上两种实现方式结果,但是Converter接口相比PropertyEditor接口更加灵活一些,PropertyEditor接口仅限于String转换,Converter可以自定义别的,并且PropertyEditor接口通常用于Controller中的接收参数的转换。
- @ConfigurationPropertiesBinding是限定符注解@Qualifier的派生类而已,参考org.springframework.boot.context.properties.ConversionServiceDeducer,以下是源代码片段
@Autowired(required=false) @ConfigurationPropertiesBinding publicvoidsetConverters(List>converters){ this.converters=converters; } /** *Alistofcustomconverters(inadditiontothedefaults)tousewhen *convertingpropertiesforbinding. *@paramconverterstheconverterstoset */ @Autowired(required=false) @ConfigurationPropertiesBinding publicvoidsetGenericConverters(List converters){ this.genericConverters=converters; }
- Formatter接口是不能对属性完成转换的,因为ConversionServiceDeducer初始化的时候只获取GenericConverter和Converter接口
- 官方文档上还介绍了可以使用实现org.springframework.core.convert.ConversionService并且Bean名称也必须叫conversionService,不过大部分情况不推荐自己通过这种方式去实现这个接口,因为自己实现的ConversionService会替代默认的。具体参考ConversionServiceDeducer源码:
publicConversionServicegetConversionService(){ try{ //默认首先寻找Bean名称叫conversionService的ConversionService的Bean类 returnthis.applicationContext.getBean( ConfigurableApplicationContext.CONVERSION_SERVICE_BEAN_NAME, ConversionService.class); } catch(NoSuchBeanDefinitionExceptionex){ //找不到就默认生成ApplicationConversionService类 returnthis.applicationContext.getAutowireCapableBeanFactory() .createBean(Factory.class).create(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。