yaml语法及其配置原理

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

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

在这里插入图片描述
建立新的application.yaml文件

在这里插入图片描述
语法格式(对空格的要求极其严格):

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

在这里插入图片描述
同时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

在这里插入图片描述
点开后进入浏览器,发现2.3.0版本的找不到,于是倒退版本。

在这里插入图片描述
在这里插入图片描述复制依赖:
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
运行测试,出现结果:
在这里插入图片描述
以及我们的yaml中还可以写占位表达。

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

访问:
在这里插入图片描述

并且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端口上:

在这里插入图片描述

二:yaml配置原理


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

在这里插入图片描述

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

在这里插入图片描述
接着我们向下找,有一个资源配置类,点进去。

在这里插入图片描述然后我们就能看到相关的配置信息。

在这里插入图片描述

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

在这里插入图片描述
然后回到我们的properties文件,这个参数恰恰在文件中被定义了。

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

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













资料参考:
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
https://space.bilibili.com/95256449?from=search&seid=4324821317013857560
https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
yaml-cpp是一个C++语言编写的YAML解析器和生成器,用于读取和编写YAML格式文件。其实现原理可以分为三个部分:Token流解析、Node构建以及Emitter输出。 1. Token流解析 yaml-cpp会将YAML文件解析成一系列的Token流,每个Token代表了YAML中的一个语法单元,例如标量、映射、列表等。Token流解析的过程可以分为两个步骤:词法分析和语法分析。 词法分析:识别并提取出YAML中的基本语法单元,例如字符串、数字、标点符号等。yaml-cpp使用正则表达式对输入的YAML文本进行词法分析。 语法分析:基于词法分析产生的Token流,对YAML文本进行语法分析,生成语法树。yaml-cpp采用递归下降的方式进行语法分析,通过分析Token流中的每个Token,逐步构建语法树。 2. Node构建 在Token流解析阶段,yaml-cpp会将YAML文本解析成一棵语法树。Node构建阶段就是在这棵语法树的基础上,构建出yaml-cpp自己的节点树。 在yaml-cpp中,每个节点都有一个类型,例如标量、映射、列表等。当解析到相应的Token时,就会创建相应类型的节点,并将其添加到节点树中。节点树的根节点是一个Sequence类型的节点,表示整个YAML文本。 3. Emitter输出 Emitter是yaml-cpp的输出模块,用于将节点树输出成YAML格式的文本。Emitter的输出过程可以分为两个步骤:编排和格式化。 编排:将节点树中的各个节点按照约定的顺序输出到文本中。例如,映射节点的键值对按照键的字典序输出。 格式化:对输出的文本进行格式化,使其易于阅读和编辑。例如,为映射节点的键值对添加缩进、换行等。 总体来说,yaml-cpp的实现原理是将输入的YAML文本解析成节点树,然后将节点树输出成YAML格式的文本。这个过程中,需要进行词法分析、语法分析、节点构建以及输出格式化等一系列处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Deeeelete

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值