资讯专栏INFORMATION COLUMN

【译】Spring Boot 2.0的属性绑定

1treeS / 2670人阅读

摘要:比如,在中,不能将属性绑定到对象。引入了新的接口,能够指出属性取值的准确位置。比如,属性绑定的验证异常现在会显示类允许你使用多个。我们计划在中继续加强的功能,而第一个想要支持的功能是不可变属性绑定。

Spring Boot2.0的属性绑定

原文
从Spring boot第一个版本以来,我们可以使用@ConfigurationProperties注解将属性绑定到对象。也可以指定属性的各种不同格式。比如,person.first-name,person.firstName和PERSON_FIRSTNAME都可以使用。这个功能叫做“relaxed binding”。

不幸的是,在spring boot 1.x,“relaxed binding”显得太随意了。从而使得很难来定义准确的绑定规则和指定使用的格式。在1.x的实现中,也很难对其进行修正。比如,在spring boot 1.x中,不能将属性绑定到java.util.Set对象。

所以,在spring boot 2.0中,开始重构属性绑定的功能。我们添加了一些新的抽象类和一些全新的绑定API。在本篇文章中,我们会介绍其中一些新的类和接口,并介绍添加他们的原因,以及如何在自己的代码中如何使用他们。

Property Sources

如果你已经使用spring有一段时间,你应该对Environment比较熟悉了。这个接口继承了PropertyResolver,让你从一些PropertySource的实现解析属性。

Spring Framework提供了一些常用的PropertySource,如系统属性,命令行属性,属性文件等。Spring Boot自动配置这些实现(比如加载application.properties)。

Configuration Property Sources

比起直接使用已存在的PropertySource实现类,Spring Boot2.0引入了新的ConfigurationPropertySource接口。我们引入这个新的接口来定义“relaxed binding”规则。

该接口的主要API显得非常简单

ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name);

另外有个IterableConfigurationPropertySource变量实现了Iterable,让你可以发现source包含的所有属性名称。

你可以向下面这样将Environment传给ConfigurationPropertySources:

Iterable sources = ConfigurationPropertySources.get(environment);

我们同时提供了MapConfigurationPropertySource来帮你应付上面的场景。

Configuration Property Names

如果规则明确,实现"relaxed binding"会简单很多。一直使用一致的格式,而不需要去关系在source中的各种无规则的格式。

ConfigurationPropertyNames类来强制进行这些属性命名规则,例如“use lowercase kebab-case names”,在代码中使用person.first-name,在source中使用person.firstName或者PERSON_FIRSTNAME.

Origin Support

如期望的那样,ConfigurationPropertySource返回ConfigurationProperty对象,里面包含了属性的取值,另外有个可选的Origin对象。

spring boot 2.0引入了新的接口Origin,能够指出属性取值的准确位置。其中TextResourceOrigin是较为常用的实现,会提供所加载的Resource,以及对应的行。

对于.properties和.yml文件,我们写了定制的souce加载器,使得追踪成为可能。一些spring boot的功能进行了重写来追踪信息。比如,属性绑定的验证异常现在会显示:

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under "person" to scratch.PersonProperties failed:

    Property: person.name
    Value: Joe
    Origin: class path resource [application.properties]:1:13
    Reason: length must be between 4 and 2147483647


Action:

Update your application"s configuration
Binder API

org.springframework.boot.context.properties.bind.Binder类允许你使用多个ConfigurationPropertySource。准确的说,Binder使用Bindable并返回一个BindResult.

Bindable

一个Bindable可以是Java bean,或是一个复杂对象(如List).这里是一些例子

Bindable.ofInstance(existingBean);
Bindable.of(Integer.class);
Bindable.listOf(Person.class);
Bindable.of(resovableType);

Binable用来携带注解的信息,但不需要太过关注这个。

BindResult

binder会返回BindResult,和java8 stream操作返回的Optional很相似,一个BinderResult表示bind的结果。

如果你尝试获取一个没有绑定的对象,会抛出异常,另外有其他的方法来设置没有绑定时的缺省对象。

var bound = binder.bind("person.date-of-birth",Bindable.of(LocalDate.class));

//返回LocalDate,如果没有则抛出异常
bound.get()

//返回一个格式化时间,或是“No DOB"
bound.map(dateFormatter::format).orElse("NO DOB");

//返回LocalDate或者抛出自定义异常
bound.orElseThrow(NoDateOfBirthException::new);
Formatting and Conversion

大部分ConfigurationPropertySource实现将值当字符串处理。当Binder需要将值转化为其他类型时,会使用到Spring的ConversionService API。比较常用的是@NumberFormat和@DateFormat这两个注解。

spring boot 2.0也引入了一些新的注解和转换器。例如,你现在可以将4s转换成Duration。具体请参考org.springframework.boot.conver包。

BindHandler

在binding的过程中,你可能会需要实现一些额外的逻辑。BindHandler接口提供了这样的机会。每一个BindHandler有onStart, onSuccess, onFailure和 onFinish方法供重载。

spring boot提供了一些handlers,用来支持已存在的@ConfigurationProperties binding。 比如 ValidationBindHandler可以用于绑定对象的合法性校验上。

@ConfigurationProperties

如文章开头所提到的,@ConfigurationProperties是在spring boot最初就加入的功能。所以大部分人会继续使用该注解是不可避免的。

Future Work

我们计划在spring boot2.1中继续加强Binder的功能,而第一个想要支持的功能是不可变属性绑定。另外相较getters和setters的绑定,使用基于构造器的绑定来代替:

public class Person{
    private final String firstName;
    private final String lastName;
    private final LocalDateTime dateOfBirth;
    public Person(String firstName, String lastName, LocalDateTime dateOfBirth){
        this.firstName = firstName;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
    }
    //getters
}
Summary

我们希望在spring boot2.0 中你可以找到更好用的属性绑定功能,并考虑升级你目前的方式。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77471.html

相关文章

  • Spring Boot 2.0 外部化配置介绍

    摘要:可以使用外部化配置来方便在不同环境的运行同样的程序文件文件环境变量命令行参数内置顺序实现了很多按以下顺序进行合理的相同属性的覆盖目录下的全局设置属性,如果激活测试用例上的注解测试用例上的注解。 简介 在应用中管理配置并不是一个容易的任务,尤其是在应用需要部署到多个环境中时。通常会需要为每个环境提供一个对应的属性文件,用来配置各自的数据库连接信息、服务器信息和第三方服务账号等。通常的应用...

    lmxdawn 评论0 收藏0
  • Spring Boot 配置文件中花样,看这一篇足矣!

    摘要:的默认配置文件位置为。比如,我们需要自定义模块的服务端口号,可以在中添加来指定服务端口为,也可以通过来指定应用名该名字在应用中会被注册为服务名。同时,配置内容都对开发人员可见,本身这也是一种安全隐患。 在快速入门一节中,我们轻松的实现了一个简单的RESTful API应用,体验了一下Spring Boot给我们带来的诸多优点,我们用非常少的代码量就成功的实现了一个Web应用,这是传统的...

    pingan8787 评论0 收藏0
  • Spring Security

    摘要:框架具有轻便,开源的优点,所以本译见构建用户管理微服务五使用令牌和来实现身份验证往期译见系列文章在账号分享中持续连载,敬请查看在往期译见系列的文章中,我们已经建立了业务逻辑数据访问层和前端控制器但是忽略了对身份进行验证。 重拾后端之Spring Boot(四):使用JWT和Spring Security保护REST API 重拾后端之Spring Boot(一):REST API的搭建...

    keelii 评论0 收藏0
  • Spring Boot 2.0 @ConfigurationProperties 使用

    摘要:引言的一个便捷功能是外部化配置,可以轻松访问属性文件中定义的属性。本文将详细介绍的使用。 引言 Spring Boot的一个便捷功能是外部化配置,可以轻松访问属性文件中定义的属性。本文将详细介绍@ConfigurationProperties的使用。 配置项目POM 在pom.xml中定义Spring-Boot 为parent org.springframework.boot...

    mating 评论0 收藏0
  • Spring Boot 配置加载顺序详解

    摘要:使用会涉及到各种各样的配置,如开发测试线上就至少套配置信息了。本章内容基于进行详解。添加测试类运行单元测试,程序输出根据以上参数动态调整,发现参数会被正确被覆盖。了解了各种配置的加载顺序,如果配置被覆盖了我们就知道是什么问题了。 使用 Spring Boot 会涉及到各种各样的配置,如开发、测试、线上就至少 3 套配置信息了。Spring Boot 可以轻松的帮助我们使用相同的代码就能...

    BetaRabbit 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<