Spring Boot中的属性绑定的实现

网友投稿 312 2023-01-09


Spring Boot中的属性绑定的实现

之前翻译了一篇不怎么样的文章,主要是翻译的水平有限,自己翻译的云里雾里,发现平时只会有@ConfigurationProperties注解,对SpringBoot强大的属性绑定知之甚少,所以以那篇文章为线索,重新学习了一遍。

@ConfigurationProperties

在使用的时候,我们往往只关心两件事,属性怎么绑定,即属性文件中的值和配置类中字段的映射关系;其次是类实例化的时机。故而衍生开来ConfigurationProperties有三种用法。

@Component + @ConfigurationProperties

这种用法最简单,直接在POJO类上加上注解即可,Spring容器初始化时就会生成配置类实例了。适合POJO类是自定义的。

@Component

@ConfigurationProperties(prefix = "kaka.cream.mail-a",ignoreUnknownFields = false)

public class MailPropertiesA {

private String name;

private String sex;

private Integer age;

@Bean + @ConfigurationProperties

在配置类中进行装配,这两个注解均出现在Configuration中,对POJO无侵入,使用灵活,且集中(均在配置类中处理)

@Bean

@ConfigurationProperties(prefix = "kaka.cream.mail-b",ignoreUnknownFields = false)

public MailPropertiesB mailPropertiesB(){

MailPropertiesB b = new MailPropertiesB();

return b;

}

@EnableConfigurationProperties + @ConfigurationProperties

Pojo类上注解@ConfigurationProperties,在启动类上注解@EnableConfigurationProperties

@Data

@ConfigurationProperties(prefix = "kaka.cream.mail-c",ignoreUnknownFields = false)

public class MailPropertiesC {

private String name;

private String sex;

private Inthttp://eger age;

}

@EnableConfigurationProperties(MailPropertiesC.class)

public class GomvcApplicationTests {

可以在启动类上一目了然的看到启动的配置,且不需要配置类,对第三方使用者比较友好,但是灵活性上没有第二种好。在这三种里面,推荐使用第二种方式。

Environment

存在于spring boot首个版本的元老类,它继承自PropertyResolver,通过它,我们能知道激活的配置文件,以及获取对应参数的值,结合上面第二种在配置类中一起用。较常用的主要有

//判断是否包含键值

boolean containsProperty(String key);

//获取属性值,如果获取不到返回null

String getProperty(String key);

//获取属性值,如果获取不到返回缺省值

String getProperty(String key, String defaultValue);

//获取属性对象

T getProperty(String key, Class targetType);

其中最后一个转换是和Converter有关的,会依据sourceType和targetType查找转换器,这个打算下一个章节进行分析,不在这里展开。所以Environment适合简单属性值的获取,不知何复杂对象的绑定。

Binder

Binder是在Spring Boot2新引入的API,从字面就可以看出来,“主打”绑定,可以非常方便的进行类型转化,以及提供回调方法介入绑定的各个阶段进行深度定制,结合上面第二种在配置类中一起用。其主要的类有Binder, BindResult和BindHandler. 比Environment好用很多,必备好类。

//绑定对象

MailPropertiesC propertiesC = Binder.get(environment).bind("kaka.cream.mail-c", Bindable.of(MailPropertiesC.class)).get();

//绑定Map

Map propMap = Binder.get(environment).bind("fish.jdbc.datasource",Bindable.mapOf(String.class, Object.class)).get();

//绑定列表

List list = Binder.get(environment).bind("kaka.cream.list",Bindable.listOf(String.class)).get();

//转换以及默认值

String datestr = (String) Binder.get(environment).bind("kaka.cream.date",Bindable.of(String.class))

.map(String::toUpperCase)

/** .map(new Function(){

@Override

public Object apply(Object o) {

String str = (String)o;

return str.toUpperCase();

}

})**/

.orElse("bad date string");

//绑定过程回调函数,高度定制

LocalDate str = Binder.get(environment).bind("kaka.cream.date", Bindable.of(LocalDate.class), new BindHandler() {

@Override

public Bindable onStart(ConfigurationPropertyName name, Bindable target,

BindContext context) {

log.info("绑定开始{}",name);

return target;

}

@Override

public Object onSuccess(ConfigurationPropertyName name, Bindable> NxfoFRtarget, BindContext context, Object result) {

log.info("绑定成功{}",target.getValue());

return result;

}

@Override

public Object onFailure(ConfigurationPropertyName name, Bindable> target, BindContext context, Exception error) throws Exception {

log.info("绑定失败{}",name);

return "没有找到匹配的属性";

}

@Override

public void onFinish(ConfigurationPropertyName name, Bindable> target, BindContext context, Object result) throws Exception {

log.info("绑定结束{}",name);

}

}).get();


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:自动化接口测试平台设计(常用的接口自动化测试框架)
下一篇:微服务网关需要什么(微服务网关技术选型)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~