yaml语法学习
1、配置文件
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
- application.properties
- 语法结构 :key=value
- application.yml
- 语法结构 :key:空格 value
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
比如我们可以在配置文件中修改Tomcat 默认启动的端口号!测试一下!
server.port=8081
2、yaml概述
YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)
这种语言以数据作为中心,而不是以标记语言为重点!
以前的配置文件,大多数都是使用xml
来配置;比如一个简单的端口配置,我们来对比下yaml和xml
传统xml配置:
<server>
<port>8081<port>
</server>
yaml配置:
server:
prot: 8080
3、yaml基础语法
1、空格不能省略,缩进不允许使用tab,只允许空格
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
4、数据类型
YAML 支持以下几种数据类型:
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值
字面量: 普通的值 [ 数字,布尔值,字符串 ]
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
k: v
注意:
- " "双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 :name: “kuang \n shen” 输出 :kuang 换行 shen - ’’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen
对象、Map(键值对)【YAML 对象】
-
对象键值对使用冒号结构表示
key: value
,冒号后面要加一个空格。 -
也可以使用
key:{key1: value1, key2: value2, ...}
。 -
还可以使用
缩进
表示层级关系;
例如:
#对象、Map格式
key:
child-key: value
child-key2: value2
较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:
?
- complexkey1
- complexkey2
:
- complexvalue1
- complexvalue2
意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]
数组( List、set )
用 -
值表示数组中的一个元素
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。
#数组
pets:
- cat
- dog
- pig
YAML 支持多维数组,可以使用行内表示:
key: [value1, value2, ...]
一个相对复杂的例子:
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W
意思是 companies
属性是一个数组,每一个数组元素又是由 id、name、price
三个属性构成。
数组也可以使用流式(flow)的方式表示:
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
复合结构
数组和对象可以构成复合结构,例:
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
转换为 json 为:
{
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}
#k=v
#对空格的要求十分高
# 普通的key-value
#注入到我们的配置类中!
name: ztb
#对象
student:
name: ztb
age: 18
#行内写法
student2: {name: ztb,age: 3}
#数组
pets:
- cat
- dog
- pig
pets2: [cat,dog,pig]
拓展:
1、纯量是最基本的,不可再分的值,包括:
- 字符串
- 布尔值
- 整数
- 浮点数
- Null
- 时间
- 日期
上述的第一点就是纯量的一个表现形式。
使用一个例子来快速了解纯量的基本使用:
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
2、引用
&
锚点和*
别名,可以用来引用:
defaults: &defaults
adapter: postgres
host: localhost
development:
database: myapp_development
<<: *defaults
test:
database: myapp_test
<<: *defaults
相当于:
defaults:
adapter: postgres
host: localhost
development:
database: myapp_development
adapter: postgres
host: localhost
test:
database: myapp_test
adapter: postgres
host: localhost
&
用来建立锚点(defaults),<<
表示合并到当前数据,*
用来引用锚点。
下面是另一个例子:
- &showell Steve
- Clark
- Brian
- Oren
- *showell
转为 JavaScript 代码如下:
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]
修改SpringBoot的默认端口号
配置文件中添加,端口号的参数,就可以切换端口;
server:
port: 8082
4、注入配置文件
yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!
yaml注入配置文件
1、在springboot项目中的resources
目录下新建一个文件application.yml
2、编写一个实体类 Dog
、Person
类;
package com.zhu.springbootstudy.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component //注册bean到容器中
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Dog {
@Value("康康")
private String name;
@Value("4")
private Integer age;
}
package com.zhu.springbootstudy.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
//@ConfigurationProperties(prefix = "person")
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/
//javaConfig 绑定我们配置文件的值,可以采取这些方式
//加载指定的配置文件
//@PropertySource(value = "classpath:ztb.properties")
@ConfigurationProperties(prefix = "person")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
//SPEL表达式取出配置文件的值
//@Value("${name}")
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
3、使用yaml配置的方式进行注入
person:
name: ztb${random.uuid}
age: ${random.int}
happy: false
birth: 2020/8/18
maps: {k1: v1,k2: v2}
lists:
- code
- music
- girl
dog:
name: ${person.hello:hello}康乐
age: 3
4、我们刚才已经把person这个对象的所有值都写好了,我们现在来注入到我们的类中!
@ConfigurationProperties
作用:
- 将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot
将本类中的所有属性和配置文件中相关的配置进行绑定
参数prefix = “person”
: 将配置文件中的person下面的所有属性一一对应
@Component //注册bean
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
5、IDEA 提示,springboot配置注解处理器没有找到,让我们看文档,我们可以查看文档,找到一个依赖!
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
6、测试
package com.zhu.springbootstudy;
import com.zhu.springbootstudy.pojo.Dog;
import com.zhu.springbootstudy.pojo.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootStudyApplicationTests {
@Autowired //DI,将狗狗自动注入进来
private Dog dog;
@Autowired
private Person person;
@Test
void contextLoads() {
System.out.println(dog);//打印看下狗狗对象
System.out.println(person);
}
}
5、加载指定的配置文件
@PropertySource
:加载指定的配置文件;@ConfigurationProperties
:默认从全局配置文件中获取值;
6、配置文件占位符
配置文件还可以编写占位符生成随机数
person:
name: ztb${random.uuid}
age: ${random.int}
happy: false
birth: 2020/8/18
maps: {k1: v1,k2: v2}
lists:
- code
- music
- girl
dog:
name: ${person.hello:hello}康乐
age: 3
7、@ConfigurationProperties与@Value比较
1、@ConfigurationProperties
只需要写一次即可 , @Value
则需要每个字段都添加
2、松散绑定:这个什么意思呢? 比如我的yml
中写的last-name
,这个和lastName
是一样的, -
后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303
数据校验 , 这个就是我们可以在字段上增加一层过滤器验证 , 可以保证数据的合法性
4、复杂类型封装,yml
中可以封装对象 , 使用value
就不支持
结论:
- 只需要获取配置文件中的某个值,使用
@value
; - JavaBean来和配置文件进行一一映射,就直接
@configurationProperties