聊聊我写Yml的亲身感受

开发 后端
我非常羞耻的发现,配置文件界,已经被下面三种所统治:yaml,toml和json,这让一直使用properties文件的javaer深深的埋下了头。

 [[403804]]

本文转载自微信公众号「小姐姐味道」,作者小姐姐养的狗。转载本文请联系小姐姐味道公众号。

我非常羞耻的发现,配置文件界,已经被下面三种所统治:yaml,toml和json,这让一直使用properties文件的javaer深深的埋下了头。

不要担心,当你读到文章最后,你也会羞愧的埋下头。也可能会有一丝愤怒。

像各种人工智能调参数,k8s调参师,都已经成功升级为yml配置大师。作为一个常年使用yml文件的SpringBoot框架使用者,有时候对yml的表现形式竟然显露出了困惑,这不由得让人羞愧又加了一层。

YAML,竟然是XML的一个子集,所以它的复杂是有源头的,最早诞生于2009年。

使用yml文件,首先遇到的问题,就是它的缩进问题。就如同python语言一样,yml文件的表现层次,是靠嵌套的缩进来完成的。它并不使用TAB,而是使用空格表示缩进。

要命的是,空格的多少,并不重要,只要相同级别元素左侧能够对齐就行。这对于CV党来说,不得不说是一个噩梦哈哈。

那一个配置文件,要解决哪些问题呢?Redis已经做出了回答。就像你学习一门新的语言一样,解决了它的字符串和集合的表示方法,基本上写代码就没问题了。那我们就挨个来看一下。

以下方法以SpringBoot的yml文件格式为准,其他场景的解析器会有些许差异。为了能够debug这些值,我们简单的写了一个测试类,然后再设值完成之后打印以下就可以了。

@EnableAutoConfiguration 
@Configuration 
public class TestConfig implements InitializingBean { 
    @Value("${str1}"
    String str1; 
    @Override 
    public void afterPropertiesSet() throws Exception { 
        System.out.println(this); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

1. 字符串

字符串是最简单的配置,也是最常见的配置。再spring中,字符串可以代引号,也可以不带引号。所以下面三行的配置效果,是一样的。

str1: ksdfjsdlkfjdsf skdfljs 
str1: 'ksdfjsdlkfjdsf skdfljs' 
str1: "ksdfjsdlkfjdsf skdfljs" 
  • 1.
  • 2.
  • 3.

那么,如何支持多行文本呢?毕竟有些需求,就是这么作死。写法如下:

str1: | 
  ksdfjsdlkfjdsf skdfljs 
  ksdfjsdlkfjdsf skdfljs 
  ksdfjsdlkfjdsf skdfljs 
  • 1.
  • 2.
  • 3.
  • 4.

注意,后面不需要有其他的画蛇添足的结束表示,一切都是靠缩进来证明的。当然,你也可以把 |换成>,效果是一样的。

str1: > 
  ksdfjsdlkfjdsf skdfljs 
  ksdfjsdlkfjdsf skdfljs 
  ksdfjsdlkfjdsf skdfljs 
  • 1.
  • 2.
  • 3.
  • 4.

要命的是,它还有第三种写法。

str1: "ksdfjsdlkfjdsf skdfljs 
  ksdfjsdlkfjdsf skdfljs 
  ksdfjsdlkfjdsf skdfljs" 
  • 1.
  • 2.
  • 3.

2. 数字

当我们的接收者,是一个数字的时候,比如下面这个。

@Value("${a}"
int a ; 
  • 1.
  • 2.

那么,你即使把配置文件写成了字符串,它也会强制转成数字。

a: "014" 
  • 1.

此时,a的数值,就会被设置成整数14。

神奇的是,如果你把引号去掉,也就是下面这样。

a: 014 
  • 1.

此时,a的数值,竟然变成了12!

我就曾碰到过这样的极品bug,浪费了不少脑细胞,wtf。因为以0开头,代表的是八进制,解析器中间做了一层转换。所以,按照这个逻辑,0x14就是20,使用时一定要注意这一点。机灵的同学可以拿来埋坑哦。

这里也有一些特殊的写法。

float: 1.23e+3     # 浮点数 
fixed: 13.67       # 固定小数 
minmin: -.inf      # 表示负无穷 
notNumber: .NaN    # 无效数字 
 
boolean: [truefalse] # 布尔值 
string: '12345'    # 字符串 
 
date: 2021-06-03   # 日期 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

3. 字典

再来看一下常见的字典。其实,把所有的配置罗列开来,本身就是一个字典,也就是kv配置。

它是以:进行分割的,所以左半部分要求不能有特殊字符,否则就晕菜了。不不不,它没有晕菜,因为它把乱七八糟的字符,正确的识别了出来。比如下面的yml配置。

a&& xk@71: 0x14 
  • 1.

这样的代码接收。

@Value("${a&& xk@71}"
int a ; 
  • 1.
  • 2.

嗯,容易被打死的写法。所以,你懂的。

还是我太幼稚了,yml文件根本就没规定key不允许有特殊字符,它允许你这么做。

4. 对象

由字典,很容易可以扩展到对象。因为对象,也是一堆属性的集合。json已经证明,这些属性,就是一堆KV,我们的yaml也是如此。

假设有如下的代码,我们需要构造dog中的数据。

@Data 
public static class Dog{ 
    private String xjjdog1; 
    private String xjjdog2; 

 
@Bean 
@ConfigurationProperties(prefix = "dog"
public Dog getDog(){ 
    return new Dog(); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

第一种yml的写法,是这样。

dog: 
  xjjdog1: i am xjjdog1 
  xjjdog2: i am xjjdog1++ 
  • 1.
  • 2.
  • 3.

而另一种方式,是把json数据直接给写到文件里。

dog: {xjjdog1: 'i am xjjdog1',xjjdog2: 'i am xjjdog++'
  • 1.

当然,多个层次,可以在一行之中平铺开。比如prefix是super.dog,那么yml文件就可以这么写。

super.dog: {xjjdog1: 'i am xjjdog1',xjjdog2: 'i am xjjdog++'
  • 1.

5. 列表支持

列表,就是list,我们可以使用数组接收,也可以使用List等。

它也有两种写法。这是最常见的一种。

animal: 
  - dog 
  - cat 
  - monkey 
  • 1.
  • 2.
  • 3.
  • 4.

当然,也可以放在一行。

animal: [dog,cat,monkey] 
  • 1.

这没什么问题,关键是yml文件支持嵌套。比如List里嵌套Map,或者Map里嵌套List。当嵌套层次比较深的时候,或者缩进没什么规律的时候,就显得非常的乱。

比如下面这个k8s的pod配置。

apiVersion: v1 
kind: Pod 
metadata: 
  name: xjjdog-Pod 
  labels: 
    app: front-web 
spec: 
  containers: 
    - name: front-web 
      image: nginx 
      ports: 
        - containerPort: 80 
    - name: front-app 
      image: xjjdog/frontapp 
      ports: 
        - containerPort: 14000 
  storages: 
  ... 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

比较复杂的是spec,里面有containers、storages等配置。其中containers是一个列表,列表之间是一个map,map中其中的ports属性,又是一个列表...如此嵌套,如果配置文件比较长的化,不熟悉业务属性的同学就会容易晕菜。

6. 特殊数据

即使是这样,yaml也比xml简单的多。它也有很多特殊的写法。

比如这个。

str1: !!str 2021-06-03 
  • 1.

它的意思是,把2021-06-04,强制转化成字符串。这样的强制转化有很多,但大多数时候你不会用。但如果你想要把你的yaml文件变得复杂,让别人不敢动,那就可以这么做。

!!int               # 整数类型 
!!float             # 浮点类型 
!!bool              # 布尔类型 
!!str               # 字符串类型 
!!binary            # 也是字符串类型 
!!timestamp         # 日期时间类型 
!!null              # 空值 
!!set               # 集合 
!!omap, !!pairs     # 键值列表或对象列表 
!!seq               # 序列,也是列表 
!!map               # 键值表 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

既然yml文件有这么多复杂的写法,那么我们就可以去玩一把。比如下面的写法。

from: &d !!str 2021-06-04 
 
str1: *d 
  • 1.
  • 2.
  • 3.

这个配置,和上面的配置,效果是一样的,&的意思是标记,我们给它起了个名字,叫做d;*的意思是引用,我们在需要它的地方引用一把就可以了。

yml中的key,竟然也可以用对象或者复杂的结构作为key。为了标识是一个特殊的key,我们还要做一点处理。

?[blue, reg, green]: Color 
  • 1.

上面这个配置的?,就是说,我下面要进行一个比较复杂的配置了,你准备好了么?

7. End

学会了这些招数的你,是不是跃跃欲试了?想要在你的SpringBoot项目里搞一点有意思的东西?为了让你的基础架构部门无法扫描出你的配置,为什么不呢?

这是我改造的一个普通datasource的配置文件。

h2: &sa !!str sa 
driver: &driver !!str org.h2.Driver 
defaults: &defaults 
  ?username: *sa 
  ?password
  ?driverClassName: *driver 
spring: 
  datasource: 
    <<: *defaults 
    ?url: !!str > 
      jdbc:h2:mem:h2test; 
      DB_CLOSE_DELAY=-1; 
      DB_CLOSE_ON_EXIT=FALSE 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

你觉得美么?我反正腿挺疼的。

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

 

责任编辑:武晓燕 来源: 小姐姐味道
相关推荐

2021-06-07 10:00:56

yml文件开发

2011-04-26 17:37:29

打印机用户体验

2014-06-27 18:22:19

2016-05-03 17:33:02

面试离职

2021-02-22 09:30:09

go开发环境桌面系统

2021-03-28 20:58:25

Go语言线程

2023-02-07 09:37:08

流计算

2020-03-13 09:38:45

离职创业感受

2024-01-22 10:18:32

平台工程开发人员技术

2021-07-02 07:06:20

调试代码crash

2014-05-26 15:20:13

产品细节工匠情怀

2023-03-29 08:31:28

写代码微服务远程

2023-04-11 08:02:26

单测技术JUnit框架

2020-03-20 09:49:59

需求编程常态

2021-06-16 07:56:48

C++新特性类型

2020-10-10 09:09:21

CTOCRUD设计

2022-09-22 09:54:56

技术选型

2011-04-27 13:25:56

佳能传真机用户体验

2025-01-06 08:00:54

2021-03-26 06:27:08

操作系统应用软件浏览器
点赞
收藏

51CTO技术栈公众号