YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达数据序列化的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC2822)中获得灵感。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与OrenBen-Kiki也是这语言的共同设计者。当前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。

官方不推荐properties文件,所以IDEA中项目自动生成的文件直接删除。

ingress yaml文件截取路径 yaml解析_spring boot


建立新的application.yaml文件

ingress yaml文件截取路径 yaml解析_spring boot_02


语法格式(对空格的要求极其严格):

【父级】
	【子级】【空格】【参数】

ingress yaml文件截取路径 yaml解析_spring_03


同时yaml支持配置的同时也可以存对象:

#存对象
student:
  name: "jack"
  age: 18

#行内形式
student1: {name: "jack",age: 77}

#存数组
list1:
  - one
  - two

#数组行内写法
list2: [one,two]

yaml甚至可以给实体类赋值:

User对象:

package com.springboot.myweb.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    
    private String name;

    private String pwd;

    public User() {
        super();
    }

    public User(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

Udetil对象:

package com.springboot.myweb.pojo;

import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public class Udetil {

    private String address;
    private int age;
    private Boolean  flag;
    private Map<String,Object> maps;
    private List<String> lists;
    private User user;

    public Udetil() {
        super();
    }

    public Udetil(String address, int age, Boolean flag, Map<String, Object> maps, List<String> lists, User user) {
        this.address = address;
        this.age = age;
        this.flag = flag;
        this.maps = maps;
        this.lists = lists;
        this.user = user;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Boolean getFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<String> getLists() {
        return lists;
    }

    public void setLists(List<String> lists) {
        this.lists = lists;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Udetil{" +
                "address='" + address + '\'' +
                ", age=" + age +
                ", flag=" + flag +
                ", maps=" + maps +
                ", lists=" + lists +
                ", user=" + user +
                '}';
    }
}

yaml配置:

udetil:
  address: "小区"
  age: 99
  flag: false
  maps: {key1: v1,k2: v2}
  lists: ["aa","bb","cc"]
  user:
    name: "jack"
    pwd: "123123"

ApplicationTests测试类:

package com.springboot.myweb;

import com.springboot.myweb.pojo.Udetil;
import com.springboot.myweb.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

@SpringBootTest
class MywebApplicationTests {

    @Resource
    private Udetil ud;

    @Test
    void contextLoads() {
        System.out.println(ud);
    }

}

当然这样不算完成,如果想要在yaml中对一个类进行赋值,还需要在对应的类上加相关的注解@ConfigurationProperties,加上后发现爆红,尽管这里的爆红并不影响程序的运行,但若果觉得爆红难受的话可以点上方open

ingress yaml文件截取路径 yaml解析_加载_04


点开后进入浏览器,发现2.3.0版本的找不到,于是倒退版本。

ingress yaml文件截取路径 yaml解析_User_05


ingress yaml文件截取路径 yaml解析_spring boot_06

复制依赖:

ingress yaml文件截取路径 yaml解析_User_07

通过进行配置来产生提示,当然想要生效需要重启IDEA,这里就暂时先不重启了。

ingress yaml文件截取路径 yaml解析_User_08

接下来需要用该注解绑定到我们yaml中配置的名称:

ingress yaml文件截取路径 yaml解析_ingress yaml文件截取路径_09


运行测试,出现结果:

ingress yaml文件截取路径 yaml解析_spring_10


以及我们的yaml中还可以写占位表达。

udetil:
  address: ${random.uuid}
  age: ${random.int}
  flag: false
  maps: {key1: v1,k2: v2}
  lists: ["aa","bb","cc"]
  user:
    name: "jack"
    pwd: "123123"

访问:

ingress yaml文件截取路径 yaml解析_spring boot_11

并且yaml可以支持指定多个配置,多个不同的配置块区可以用- - -来区分,使用spring: profiles: 【name】指定名称,spring.profiles.active指定使用

server:
  port: 8044



udetil:
  address: ${random.uuid}
  age: ${random.int}
  flag: false
  hello: hyyyyyy
  maps: {key1: v1,k2: v2}
  lists: ["aa","bb","cc"]
  user:
    name: ${udetil.hello:hello}_jack
    pwd: "123123"

#spring.profiles.active用于指定使用哪个模块的配置
spring:
  profiles:
    active: dev
---
server:
  port: 8043
spring:
  profiles: dev
---
server:
  port: 8045
spring:
  profiles: test

则会运行在dev指定的8043端口上:

ingress yaml文件截取路径 yaml解析_ingress yaml文件截取路径_12

二:yaml配置原理



文件配置自然是在yaml文件中进行,而yaml中所涉及到的配置非常之多,且有一些配置springboot会默认给加载进去,这里先简单介绍一下这些加载的流程。 因为我们已知springbootApplication注解最终挖取了一个spring.factories的关键文件,该文件中存在大量类似于url之类的东西,可单纯的url是无法完成一个个复杂配置的,因此它背后必然有一个类来替它完成复杂的配置任务,拿常见的webmvc来说,点进去。

ingress yaml文件截取路径 yaml解析_spring_13

接下来我们看到,点进去的配置类中存在一个@Configuration注解将其声明为一个配置类,然后是众多Conditiona开头的注解,这个注解就是在动态的判定项目需不需要引入此类配置,因为刚才我们看到spring.factories文件中存在如此多的配置,而我们的项目并不一定需要将它们全部的加载进去,毕竟我们项目中不需要的配置还要加载进去拿就实数浪费了,而这些Conditiona就是为此而出现的,如果项目不满足这些前置配置条件,那就停止引入配置。

ingress yaml文件截取路径 yaml解析_ingress yaml文件截取路径_14


接着我们向下找,有一个资源配置类,点进去。

ingress yaml文件截取路径 yaml解析_spring_15

然后我们就能看到相关的配置信息。

ingress yaml文件截取路径 yaml解析_User_16

于是我们尝试在yaml文件中书写spring.resources这个参数,可以看到这里出现了一个 addMappings参数。

ingress yaml文件截取路径 yaml解析_spring boot_17


然后回到我们的properties文件,这个参数恰恰在文件中被定义了。

ingress yaml文件截取路径 yaml解析_ingress yaml文件截取路径_18

如果你这里在yaml文件中还配置了端口的信息,当点进去的时候也会发现页面进入到了一个以XXXproperties结尾的配置文件中, 而配置文件中所定义的参数,也正好是我们在yaml文件中能够进行配置的参数。

这也就解释了,为什么我们的项目在不配置端口的时候默认走了8080,因为这些properties文件中已经存在了默认配置,且会被springboot加载并生效,但因为yaml文件级别较高,一旦我们重写了其配置,那项目会优先生效我们自定义的配置。所以说,yaml文件中能够配置的是已经存在了的配置,而这些配置则被具体的定义在了对应的properties文件中,文件最终被配置文件引入,而配置文件又写在了spring.factories文件中,并最终被系统加载。





资料参考:
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/