yaml
1、yaml 语法
Spring Boot 配置文件中可以配置哪些东西呢?官方的配置比较多,还是要了解原理。
-
将 resource 目录下的 application.properties 文件删掉,新建 application.yaml 文件,yaml文件是 Spring 推荐的配置文件格式。
application.properties 的语法结构是 key = value
application.yml 的语法结构是 key: value( key + 英文冒号 + 空格 + value)
-
配置文件的作用是修改 Spring Boot 自动配置的默认值,因为 Spring Boot 在底层已经都自动配置好了。
YAML是 “ YAML Ain’t a Markup Language ” (YAML不是一 种置标语言)的递归缩写。
在开发的这种语言时,YAML的意思其实是:“ Yet Another Markup Language ” (仍是一种置标语言)
YAML A Markup Language:是一个标记语言
YAML isnot Markup Language:不是一个标记语言
-
yaml 语法:对空格的要求极其严格。
# 普通的key-value name: yuhaiyang # 对象 student: name: yuhaiyang age: 18 # 行内写法 student: {name: yuhaiyang,age: 18} # 数组 pets: - cat - dog - pig # 行内写法 pets: [cat,dog,pig]
2、yaml 注入配置文件
yaml文件更强大的地方在于,可以给实体类直接注入匹配值!
1、编写一个实体类 Dog 。
@Component //将bean注册到容器中
public class Dog {
private String name;
private Integer age;
//有参无参构造、get、set方法、toString()方法
}
2、以下是原来给 bean 注入属性值的方法,使用 @Value 注解。
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dog {
@Value("大黄")
private String name;
@Value("3")
private Integer age;
}
3、在 SpringBoot 测试类进行测试输出。
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired // 将dog自动注入进来
private Dog dog;
@Test
void contextLoads() {
System.out.println(dog);
// 输出结果:Dog(name=大黄, age=3)
}
}
4、然后编写一个 Person 实体类,这个实体类的属性多一些。
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
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、接下来使用 yaml 的方式对 Person 进行注入,在 SpringBoot 项目中的 resources 目录下新建 application.yaml 文件,进行编写。
person:
name: yuhaiyang
age: 18
happy: false
birth: 2000/09/17
maps: {k1: v1,k2: v2}
lists:
- code
- girl
- music
dog:
name: 旺财
age: 1
6、在 Person 实体类上方加入 @ConfigurationProperties 注解,加上后上方会报红,其实不影响,在依赖中加入以下内容后重启即可。
@ConfigurationProperties(prefix = "person")
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
7、在 SpringBoot 测试类进行测试输出。
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired
private Person person;
@Test
void contextLoads2() {
System.out.println(person);
// 输出结果:Person(name=yuhaiyang, age=18, happy=false, birth=Sun Sep 17 00:00:00 CST 2000, maps={k1=v1, k2=v2}, lists=[code, girl, music], dog=Dog(name=旺财, age=1)),注入成功!
}
}
8、补充:
-
将 yaml 配置文件的 key 值 和 属性的值设置为不一样,则结果输出为null,注入失败。
-
再配置一个person2,然后将使用
@ConfigurationProperties(prefix = "person2")
指向 person2,即可将person2 注入到 Person 对象中。 -
配置文件占位符
person: name: qinjiang${random.uuid} # 随机uuid age: ${random.int} # 随机int happy: false birth: 2000/01/01 maps: {k1: v1,k2: v2} lists: - code - girl - music dog: # 引用person.hello的值,如果不存在就用 : 后面的值,即other,然后拼接上_旺财 name: ${person.hello:other}_旺财 age: 1
3、properties 注入配置文件
【注意】properties配置文件在写中文的时候,会有乱码,需要去IDEA中设置编码格式为UTF-8:设置中搜索 propertie 找到File Encodings 进行配置。
1、新建一个类似于之前的 Dog 实体类 Cat(略)。
2、新建 mycat.properties 配置文件。
name=小咪咪
age=100
3、在实体类上加上 @PropertySource 注解,并在后边的 value 表明对应的配置文件。
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
@PropertySource(value = "classpath:mycat.properties")
public class Cat {
@Value("${name}")
private String name;
@Value("${age}")
private int age;
}
4、测试,测试结果表明 Cat 对象属性注入成功。
Cat(name=小咪咪, age=100)
4、对比:yaml 方式注入的优点
@Value 这个注解使用起来并不友好,需要为每个属性单独注解赋值,比较麻烦!
-
@ConfigurationProperties 注解只需要写一次即可 , 批量注入文件中的属性,@Value则需要每个字段都添加,需要一个个指定。
-
yaml 支持松散绑定:比如我的 yaml 中写的 key 值为 last-name,这个和 实体类中 lastName 是一样的,- 后面跟着的字母默认是大写的,这就是松散绑定,可以测试一下。
-
JSR303数据校验,我们可以在字段是增加一层过滤器验证,可以保证数据的合法性。
-
复杂类型封装,yaml 中可以封装对象,使用 value 就不支持。
结论
- 配置yml和配置properties都可以获取到值 , 强烈推荐 yaml。
- 如果在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value。
- 如果说,我们专门编写了一个 JavaBean 来和配置文件进行一一映射,就直接使用 @ConfigurationProperties,不要犹豫!
5、扩展:JRS303数据校验
SpringBoot 中可以用 @validated 注解来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。以下是让 name 只能支持 Email 格式的一个注解。
@Component //注册bean
@ConfigurationProperties(prefix = "person")
@Validated //数据校验
public class Person {
@Email(message="邮箱格式错啦!") //name必须是邮箱格式,message是自己定义的错误提示信息。
private String name;
}
@Email 报错的话需要加入以下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
下面是数据校验的常见使用。
@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能超过120")
private int age;
@Email(message="邮箱格式错误")
private String email;
// 空检查
@Null // 验证对象是否为 null
@NotNull // 验证对象是否不为 null,无法查检长度为0的字符串。
@NotBlank // 检查约束字符串是不是 null 还有被 Trim 的长度是否大于0,只对字符串且会去掉前后空格。
@NotEmpty // 检查约束元素是否为 null 或者是 EMPTY 。
// Booelan检查
@AssertTrue // 验证 Boolean 对象是否为 true
@AssertFalse // 验证 Boolean 对象是否为 false
//长度检查
@Size(min=, max=) // 验证对象(Array,Collection,Map,String)的长度是否在给定的范围之内
@Length(min=, max=) // string is between min and max included.
//日期检查
@Past // 验证 Date 和 Calendar 对象是否在当前时间之前
@Future // 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern // 验证 String 对象是否符合正则表达式的规则
//除此以外,还可以自定义一些数据校验规则。
以下是在相关依赖的注解源码位置,可以看出可用注解如下。