【SpringBoot框架学习】yml/yaml语法 详解

Youzg LOGO

基本知识点:

什么是yml/yaml?:

YAML是 "YAML Ain't a Markup Language" (YAML不是一种标记语言)的 递归缩写
在开发的这种语言时,YAML 的意思其实是:
"Yet Another Markup Language"(仍是一种标记语言)
这种语言以数据作为中心,而不是标记语言重点

为什么要使用yml/yaml来进行开发?

优点

  1. 语法要简单灵活
  2. 能够写注释
  3. 能够比较方便的覆盖参数值(方便书写或者debug)
  4. 能够重用配置片段
    比较大一点的project中,
    经常有很多地方的配置需要保持一致,
    最好的办法就是引入变量引用的概念
  5. 可以继承

基本语法:

八大基本类型 + 字符串:

格式

目标成员名: 普通的值

注意

  1. 字符串默认不用加上双引号或者单引号
  2. '' (单引号):
    不会 转义 字符串里面的特殊字符
    特殊字符最终会变成和普通字符一样输出

比如:msg: 'hello \n spring boot'
输出:hello \n spring boot

  1. "" (双引号):
    转义特殊字符
    特殊字符会作为本身想表示的意思

比如:
msg: "hello \n spring boot"
则会 输出 :hello 换行 spring boot


对象:

格式

目标对象名:
	对象的成员1: 1成员的值
	对象的成员2: 2成员的值
	...

Map(双列集合):

格式

目标map的名称:
	key1: value1
	key2: value2
	...

数组(List、Set 等单列集合):

格式

目标单列集合名:
 - 集合中的值1
 - 集合中的值2
 - 集合中的值3
 - ...

目标单列集合名: [集合中的值1, 集合中的值2, 集合中的值3, ...]

注意点:

  1. :(冒号)后的空格不能省略
  2. 以缩进来控制层级关系,
    只要是左边对齐的一列数据都是同一个层级的
  3. 属性和值的大小写都是十分敏感的

属性的注入:

在本人之前的博文中曾讲到过:
配置文件目的 是:

配置文件中的值注入给代码中 需要的地方

在SpringBoot中,提供了相关的注解,来注入相应的值:

@ConfigurationProperties注解:

作用

一般都是配合该注解的 prefix属性
来指定要进行注入的 配置的值

注意

  1. prefix属性的值,为配置文件中的 要赋值的段落名
  2. 实体类中要被赋值的成员名,要与 配置文件中的对应段落名 一致

例如:

pet:
  name: "吉吉国王"
  yell: "呜~"
package edu.youzg.demo.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Author: Youzg
 * @CreateTime: 2020-06-17 15:17
 * @Description: 带你深究Java的本质!
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "pet")
@Component
public class Pet {
    private String name;
    private String yell;
}

随机数 的生成:

格式

${random.随机数的类型}

而上述的 随机数类型,总共分为 4种
分类

  • int(可设置上限值)
  • long(可设置上限值)
  • uuid(随机字符串,更不容易 重复)
  • value(随机字符串)

例如:

id: ${random.uuid}  # value int long

@ConfigurationProperties注解 作为 springBoot 所提供的属性注入注解,
也提供了一些非常强大的功能,其中最常用的就是 松散绑定

松散绑定:

定义

yml/yaml配置文件 中 配置 的 键名为 xx_xx形式
实体类成员名驼峰式
也可进行注入

例如:

myFan:
  the_pets:
    - name: "加菲"
      yell: "喵~"
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "myFan")
public class Fan {
    private List<Pet> thePets;
}

讲到 属性的注入问题,有的同学可能就会想到:
当初学习spring Framework的时候,所使用的 @Value注解

那么,现在本人就来讲解下 @ConfigurationProperties注解@Value注解 之间的 区别 以及 各自的应用场景

@ConfigurationProperties注解 与 @Value注解:

首先本人来列举下这两个注解的区别

区别:

比较项目 @ConfigurationProperties @Value
功能 批量注入 配置文件中的属性 一个个指定注入 配置文件中的属性
松散绑定 支持 不支持
SpEL 不支持 支持
JSR303校验 支持 不支持
复杂封装类型 支持 不支持

那么,区别这么多,这两个注解的应用场景是什么呢?

应用场景:

  • @Value注解
    只是在某个业务逻辑中需要获取一下配置文件中的某项值
  • @ConfigurationProperties注解
    专门编写了一个JavaBean来和配置文件进行映射

在有些情况下,我们不希望application配置文件中的属性配置太过繁琐
需要将有些属性的配置放到其它的配置文件中去
那么,针对这种需求,springBoot提供了 @PropertySource注解

注入 其它配置文件的属性 —— @PropertySource注解:

例如:
首先,本人来提供一个 pet.properties配置文件

pet.name=killer queen
pet.yell=wryyyyyyyyy

接下来,我们来修改下 Pet类 的 内容:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@PropertySource({"classpath:pet.properties"})	// 指定要被 “额外加载” 的配置文件的 全路径名
@ConfigurationProperties(prefix = "pet")	// 指定前缀
@Component
public class Pet {
    private String name;
    private String yell;
}

那么,我们来做个小测试:

import edu.youzg.entity.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ProfileDemoApplicationTests {

    @Autowired
    private Pet myPet;
    
    @Test
    public void myTest() {
        System.out.println(myPet);
    }

}

运行结果:
运行结果 展示


多配置文件 问题:

在有的大型项目中,我们或许能够看到 这样的情况:
一个项目,配置了多个配置文件(即:配置了多个application.yml)

配置文件 优先级:

springBoot提供了 四个 可以 放置配置文件 的 位置

  1. file: ./config(项目路径下的config文件夹配置文件)
  2. file: ./(项目路径下配置文件)
  3. classpath: /config(资源路径下的config文件夹配置文件)
  4. classpath: /(资源路径下配置文件)

如下图所示:
优先级 展示


指定 开发环境:

在我们今后的工作中,可能会遇到这样的情况:

在测试开发时,操作的是一些数据库
在产品发布时,使用的是另一些数据库

那么,这样的话,我们就需要配置多套配置文件,操作起来比较麻烦
因此,spring Boot 提供了切换开发环境的功能:

核心操作:

在application-default.yml文件中,增加如下代码:

spring:
  profiles:
    active: 指定的配置文件的“后缀名”

例如:

首先,我们需要一个默认的配置文件
其 文件名 必须为:application-default.yml(或 application-default.properties):

server:
  port: 8085

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/dbstudy?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
  devtools:
    restart:
      log-condition-evaluation-delta: true
      exclude: static/css/**, static/js/**
  thymeleaf:
    cache: false
    prefix: classpath:/templates/views/
    suffix: .html
  # 指定开发环境(指定配置文件中 没配置则填充,配置了则覆盖)
  profiles:
    active: dev
    
#mapper-locations 映射所在的路径
#给模型的包起个别名
mybatis:
  mapper-locations: classpath:/mapper/*Mapper.xml
  type-aliases-package: edu.youzg.about_boot.model

#打印日志 SQL 执行
logging:
  level:
    edu:
      youzg:
        about_boot:
          mapper: debug

(本例 主要是 配置port,以及 指定了环境的配置)


之后,本人再来给出 开发环境产品环境配置文件
application-dev.yml

server:
  port: 8100

application-prod.yml

server:
  port: 8090

那么,当我们再次运行时,控制台就会显示如下结果:
指定环境 展示
可以看到:端口号变为了我们指定的端口


多配置文件 的合并:

若是我们想要在激活一个配置文件同时激活多个配置
就需要在目标开发环境中,加入

spring:
	profiles:
		include: 
			- 指定的配置文件的“后缀名1”
			- 指定的配置文件的“后缀名2”,
			- ...

(注意:若重名include中的值覆盖 原配置文件的值


但是,如上的多开发环境也可以在一个配置文件中实现:

单配置文件 配置 多开发环境:

核心步骤:

将每个 子开发环境 放在主开发环境下,
并使用

---

分隔开,
再通过

spring:
  profiles:
    active: 指定的配置文件的“后缀名”

来指定

例子:

server:
  port: 8080

spring:
  profiles:
    active: test

---
spring:
  profiles: test
server:
  port: 9000

---
spring:
  profiles: production
server:
  port: 9050

那么,当我们运行之后,控制台就会显示如下结果:
指定开发环境 展示


使用展示:

本人先来给出一个宠物类

package edu.youzg.demo.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Author: Youzg
 * @CreateTime: 2020-06-17 15:17
 * @Description: 带你深究Java的本质!
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "pet")
@Component
public class Pet {
    private String name;
    private String yell;
}

接下来,本人给出一个 粉丝类

package edu.youzg.demo.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @Author: Youzg
 * @CreateTime: 2020-06-17 15:13
 * @Description: 带你深究Java的本质!
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "myFan")
public class Fan {
    private String name;
    private String id;
    private Date birthday;
    private Integer age;
    private List<Pet> thePets;
}

对应的 yml配置文件

myFan:
  name: "右转哥的小迷妹"
  id: ${random.uuid}  # value int long
  birthday: 2020/6/18
  the_pets:
    - name: "加菲"
      yell: "喵~"
    - name: "史努比"
      yell: "汪~"

最后是 测试类

package edu.youzg.demo;

import edu.youzg.demo.model.Fan;
import edu.youzg.demo.model.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoApplicationTests {
    @Autowired
    private Fan fan;

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

}

现在,本人来展示下运行结果
运行结果 展示
可以看到:
本人没有配置age成员的值,
因此,除了age成员为null,其余成员的值都为配置文件中所配置的值

posted @ 2020-06-19 13:56  在下右转,有何贵干  阅读(4240)  评论(0编辑  收藏  举报