SpringBoot自定义属性编辑器(2022.11.09)
用途
将读取到的配置文件属性, 转换成为实体成员属性变量值, 例如下面的例子读取
yml
配置文件的JSON字符串属性, 直接注入到实体中的JSON对象
application.yml
server:
port: 80
my:
jsonConfig: "{'name':'哈哈哈哈哈'}"
将通过
@Value("${my.jsonConfig}")
注解直接读取解析成为Spring托管的Bean中的JSON对象属性@Value("${my.jsonConfig}") private JSONObject jsonObject;
1.0 自定义属性编辑器注册商
/**
* @Author: ZhiHao
* @Date: 2022/11/9 18:23
* @Description: 自定义属性编辑器注册商
* @Versions 1.0
**/
public class MyPropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
// 注册一个针对JSONObject类型的编辑器, MyPropertyEditor是自定义的编辑器
registry.registerCustomEditor(JSONObject.class,new MyPropertyEditor());
}
}
2.0 自定义属性编辑器
/**
* @Author: ZhiHao
* @Date: 2022/11/9 18:18
* @Description: 自定义属性编辑器
* @Versions 1.0
**/
public class MyPropertyEditor extends PropertyEditorSupport {
/**
* 重写PropertyEditorSupport该setAsText方法
*
* @param text
* @author: ZhiHao
* @date: 2022/11/9
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
// 判断属性字符串是否是JSON字符串, 是则进行解析并且设置到value属性
if (JSONUtil.isJson(text)) {
setValue(JSONUtil.parse(text));
}
}
}
3.0 配置到Spring_IOC中
@Configuration
public class MyConfig {
/**
* 注册配置一个自定义编辑器配置器CustomEditorConfigurer
*
* @return CustomEditorConfigurer
* @author: ZhiHao
* @date: 2022/11/9
*/
@Bean
public CustomEditorConfigurer CustomEditorConfigurer(){
CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
//设置属性编辑器注册器, 可多个
customEditorConfigurer.setPropertyEditorRegistrars(new PropertyEditorRegistrar[]{new MyPropertyEditorRegistrar()});
// 指定BeanFactoryPostProcessor 后处理器优先级
customEditorConfigurer.setOrder(Ordered.HIGHEST_PRECEDENCE);
return customEditorConfigurer;
}
}
4.0 Bean中注入属性使用
@RestController
@RequestMapping("/account")
public class TestController {
// 直接DI依赖注入类型是个JSON对象
@Value("${my.jsonConfig}")
private JSONObject jsonObject;
@GetMapping("/loginsss")
public String testsss(){
System.out.println(jsonObject);
System.out.println(jsonObject.keySet());
System.out.println(jsonObject.values());
return "成功啦";
}
}
// 访问接口输出了
{"name":"哈哈哈哈哈"}
[name]
[哈哈哈哈哈]
到这里是不是发现了和一个
@ConfigurationProperties
注解功能也能提供直接是注入一个实体,@ConfigurationProperties
是直接读取配置文件符合前缀中的key到对应实体中的, 但是如果后面很多不确定的和不可预知的配置属性, 就可以使用上面这个进行读取JSON字符串直接在Bean注入成为JSON对象使用, 例如:send.confirmCode.jsonConfig: "{ "switchType": "condition", "excludeOrderFroms": [ "ikea", "applet" ], "excludeOrderCategory": [ "1" ] }"
后面业务发现, 需要不断增加一些配置属性, 而且都是多个属性组成一个配置项的, 或者用到了动态配置中心, 不写属性转换编辑器就需要注入的是字符串,
@Value("${send.confirmCode.jsonConfig}") private String sendConfirmCodeJsonConfig;
代码里面
JSON.parseObject(el);
手动转换成为JSON对象使用, 很多重复转换代码, 所以自定义属性转换器以减少代码
扩展:
另一种方式, 添加转换器实现
@Component // 将String转成JSONObject
public class MyConverter implements Converter<String, JSONObject>, BeanFactoryPostProcessor {
@Override
public JSONObject convert(String source) {
return JSONUtil.parseObj(source);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
ApplicationConversionService conversionService = (ApplicationConversionService) beanFactory.getConversionService();
// 添加当前转换器
conversionService.addConverter(this);
}
}
1