Spring YAML与Properties

2023/05/12

1. 简介

YAML是配置文件中使用的一种人性化的表示法,为什么我们更喜欢这种数据序列化而不是Spring Boot中的属性文件?除了可读性和减少重复之外,YAML还是为部署编写配置即代码的完美语言。

同样,将YAML用于Spring DevOps有助于在环境中存储配置变量,正如12因素身份验证器所建议的那样。

在本教程中,我们将比较Spring YAML与properties文件,以检查使用其中一个的主要优势。但请记住,选择YAML而不是属性文件配置有时取决于个人喜好。

2. YAML符号

YAML代表“YAML Ain’t Markup Language”的递归首字母缩写词,它提供了以下特性:

  • 更清晰和人性化
  • 非常适合分层配置数据
  • 它支持Map、List和标量类型等增强功能

这些功能使YAML成为Spring配置文件的完美伴侣,对于那些刚开始使用YAML的人,请注意:由于其缩进规则,一开始编写它可能有点乏味。

让我们看看它是如何工作的!

3. Spring YAML配置

如前几节所述,YAML是一种特殊的配置文件数据格式,它的可读性要高得多,并且它提供了比属性文件更强大的功能。因此,在属性文件配置上推荐这种表示法是有意义的。此外,从1.2版本开始,YAML是JSON的超集

此外,在Spring中,放置在工件外部的配置文件覆盖了打包jar内部的配置文件。Spring配置的另一个有趣的特性是可以在运行时分配环境变量,这对于DevOps部署极为重要。

Spring Profile允许分离环境并对它们应用不同的属性,YAML增加了在同一个文件中包含多个Profile的可能性。

注意:Spring Boot 2.4.0的属性文件也支持此功能。

在我们的例子中,为了部署目的,我们将有三个Profile:test、dev和prod:

spring:
    profiles:
        active:
            - test

---

spring:
    config:
        activate:
            on-profile: test
name: test-YAML
environment: testing
servers:
    - www.abc.test.com
    - www.xyz.test.com

---

spring:
    config:
        activate:
            on-profile: prod
name: prod-YAML
environment: production
servers:
    - www.abc.com
    - www.xyz.com

---

spring:
    config:
        activate:
            on-profile: dev
name: ${DEV_NAME:dev-YAML}
environment: development
servers:
    - www.abc.dev.com
    - www.xyz.dev.com

注意:如果我们使用2.4.0之前的Spring Boot版本,我们应该使用spring.profiles属性而不是我们在这里使用的spring.config.activate.on-profile。

现在让我们检查一下默认分配test环境的spring.profiles.active属性,我们可以使用不同的Profile重新部署工件,而无需重新构建源代码。

Spring中另一个有趣的功能是你可以通过环境变量启用Profile

export SPRING_PROFILES_ACTIVE=dev

我们将在测试部分看到这个环境变量的相关性。最后,我们可以配置YAML属性,直接从环境中分配值:

name: ${DEV_NAME:dev-YAML}

我们可以看到,如果没有配置环境变量,则使用默认值dev-YAML。

4. 减少重复和可读性

YAML的层次结构提供了减少配置属性文件上层的方法,让我们看一个例子的区别:

component:
    idm:
        url: myurl
        user: user
        password: password
        description: >
            this should be a long 
            description
    service:
        url: myurlservice
        token: token
        description: >
            this should be another long 
            description

如果使用属性文件,相同的配置将变得多余:

component.idm.url=myurl
component.idm.user=user
component.idm.password=password
component.idm.description=this should be a long description
component.service.url=myurlservice
component.service.token=token
component.service.description=this should be another long description

YAML的分层特性极大地增强了易读性,这不仅是避免重复的问题,而且使用得当的缩进也完美地描述了配置的内容和用途。使用YAML,就像带有反斜杠\的属性文件一样,可以使用>字符将内容分成多行。

5. List和Map

我们可以使用YAML属性文件配置List和Map

有两种方法可以分配值并将它们存储在List中:

servers:
    - www.abc.test.com
    - www.xyz.test.com

external: [ www.abc.test.com, www.xyz.test.com ]

这两个示例提供相同的结果,使用属性文件的等效配置将更难阅读:

servers[0]=www.abc.test.com
servers[1]=www.xyz.test.com

external=www.abc.test.com, www.xyz.test.com

同样,YAML版本更易于阅读和清晰。

以同样的方式,我们可以配置Map:

map:
    firstkey: key1
    secondkey: key2

6. 测试

现在,让我们检查一切是否按预期工作,如果我们检查应用程序的日志记录,我们可以看到默认选择的环境是test:

16:13:02.033 [main] INFO  [c.t.taketoday.yaml.MyApplication] >>> Starting MyApplication using Java 17.0.5 on tuyucheng with PID 21988
...
using environment:testing
name:test-YAML
enabled:false
servers:[www.abc.test.com, www.xyz.test.com]
external:[www.abc.test.com, www.xyz.test.com]
map:{firstkey=key1, secondkey=key2}
Idm:
   Url: myurl
   User: user
   Password: password
   Description: this should be a long description

Service:
   Url: myurlservice
   Token: token
   Description: this should be another long description

我们可以通过在环境中配置DEV_NAME来覆盖名称:

export DEV_NAME=new-dev-YAML

我们可以看到环境的名称发生了变化,并使用dev Profile执行应用程序:

16:13:03.659 [main] INFO  [c.t.taketoday.yaml.MyApplication] >>> Starting MyApplication using Java 17.0.5 on tuyucheng with PID 26543
...
using environment:development
name:new-dev-YAML
servers:[www.abc.dev.com, www.xyz.dev.com]

让我们使用SPRING_PROFILES_ACTIVE=prod运行生产环境:

export SPRING_PROFILES_ACTIVE=prod

16:13:05.347 [main] INFO  [c.t.taketoday.yaml.MyApplication] >>> Starting MyApplication using Java 17.0.5 on tuyucheng with PID 34436
...
using environment:production
name:prod-YAML
servers:[www.abc.com, www.xyz.com]

7. 总结

在本教程中,我们描述了与属性文件相比使用YAML配置的复杂性,并演示了YAML提供的人类友好的能力,它减少了重复并且比使用属性文件更简洁。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章