引言
当我们通过@configurationproperties注解实现配置 bean的时候,如果默认的配置属性转换无法满足我们的需求的时候,我们可以根据自己的需求通过以下扩展方式对配置属性进行转换
propertyeditorsupport实现
下面的例子是把属性中定义的字符串转换成movie,并且把name的值大写
继承propertyeditorsupport并且实现propertyeditorregistrar接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package com.paderlol.spring.practice.properties.editor;
import com.paderlol.spring.practice.properties.pojo.movie;
import java.beans.propertyeditorsupport;
import lombok.extern.slf4j.slf4j;
import org.springframework.beans.propertyeditorregistrar;
import org.springframework.beans.propertyeditorregistry;
/**
* @author pader propertyeditor 在不同的包下面
*/
@slf4j
public class custommovieeditor extends propertyeditorsupport
implements propertyeditorregistrar {
@override
public string getastext() {
movie movie = (movie) getvalue();
return movie == null ? "" : movie.getname();
}
@override
public void setastext(string text) throws illegalargumentexception {
log.info( "继承[propertyeditorsupport]类,转换数据={}" , text);
string[] data = text.split( "-" );
movie movie = movie.builder().name(data[ 0 ]
.touppercase()).seat(integer.parseint(data[ 1 ]))
.build();
setvalue(movie);
}
@override
public void registercustomeditors(propertyeditorregistry registry) {
registry.registercustomeditor(movie. class , this );
}
}
|
注册自定义的propertyeditor
1
2
3
4
5
6
7
8
9
10
11
12
|
@bean
public customeditorconfigurer customeditorconfigurer() {
customeditorconfigurer customeditorconfigurer = new customeditorconfigurer();
// 有两种注册方式 这是第一种
customeditorconfigurer.setpropertyeditorregistrars(
new propertyeditorregistrar[]{ new custommovieeditor() });
// 第二 种
map< class <?>, class <? extends propertyeditor>> maps = new hashmap<>();
maps.put(movie. class ,custommovieeditor. class );
return customeditorconfigurer;
}
|
converter接口+@configurationpropertiesbinding注解
1
2
3
4
5
6
7
8
9
10
11
12
|
//注意
@component
@configurationpropertiesbinding
public class stringtopersonconverter implements converter<string, person> {
@override
public person convert(string from) {
log.info( "使用[converter]接口,转换数据={}" , from);
string[] data = from.split( "," );
return person.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,以下是源代码片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@autowired (required = false )
@configurationpropertiesbinding
public void setconverters(list<converter<?, ?>> converters) {
this .converters = converters;
}
/**
* a list of custom converters (in addition to the defaults) to use when
* converting properties for binding.
* @param converters the converters to set
*/
@autowired (required = false )
@configurationpropertiesbinding
public void setgenericconverters(list<genericconverter> converters) {
this .genericconverters = converters;
}
|
- formatter接口是不能对属性完成转换的,因为conversionservicededucer初始化的时候只获取genericconverter和converter接口
- 官方文档上还介绍了可以使用实现org.springframework.core.convert.conversionservice并且bean名称也必须叫conversionservice,不过大部分情况不推荐自己通过这种方式去实现这个接口,因为自己实现的conversionservice会替代默认的。具体参考conversionservicededucer源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public conversionservice getconversionservice() {
try {
//默认首先寻找bean名称叫conversionservice的conversionservice的bean类
return this .applicationcontext.getbean(
configurableapplicationcontext.conversion_service_bean_name,
conversionservice. class );
}
catch (nosuchbeandefinitionexception ex) {
//找不到就默认生成applicationconversionservice类
return this .applicationcontext.getautowirecapablebeanfactory()
.createbean(factory. class ).create();
}
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://segmentfault.com/a/1190000016941868