参考文档:
配置文件
自动生成的spring boot项目中的配置文件是application.properties,可将其替换为yaml文件。
从pom.xml中进入到org.springframework.boot中可以发现一段代码:
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/application*.yml</include>
<include>**/application*.yaml</include>
<include>**/application*.properties</include>
</includes>
</resource>
可见,配置文件都是以application开头的,并且后缀是yml、yaml、properties其中任意一个。
yaml基本语法
YAML是 "YAML Ain't a Markup Language" (YAML不是一种置标语言)的递归缩写。
在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种置标语言)
YAML A Markup Language :是一个标记语言
YAML isnot Markup Language :不是一个标记语言
自动生成的spring boot项目中的配置文件是application.properties,可将其替换为yaml文件
标记语言
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
基础语法:
k:(空格) v
存储形式
yaml与properties相比,其最大的优势就是存储格式多种多样。
其他
# 支持随机数
age: 27${random.int}
# 默认值 如果person.name没有值就赋值为果果
dog:
name: ${person.name:果果}
age: 3
注意
- 以空格分隔键值对,空格不能省略。
- 以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的,缩进及其严格。
- 属性和值的大小写都是十分敏感的。
对象赋值
1.spring传统方式@Value("")
package com.example.demo0211.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Dog {
//spring传统赋值方式
@Value("果果")
private String name;
@Value("4")
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.通过yaml配置+@ConfigurationProperties(prefix = "")(推荐)
实体对象文件:
package com.example.demo0211.pojo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 通过yaml配置自动映射出属性值
* prefix的值为yaml中的key,通过ConfigurationProperties注解会扫描yaml文件中的所有配置
* 对象的属性值就是yaml中的值
*/
@ConfigurationProperties(prefix = "person")
@Component
public class Person {
private String name;
private int age;
private boolean isp;
private Date birth;
private Map<String,String> job;
private List classmates;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isIsp() {
return isp;
}
public void setIsp(boolean isp) {
this.isp = isp;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, String> getJob() {
return job;
}
public void setJob(Map<String, String> job) {
this.job = job;
}
public List getClassmates() {
return classmates;
}
public void setClassmates(List classmates) {
this.classmates = classmates;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", isp=" + isp +
", birth=" + birth +
", job=" + job +
", classmates=" + classmates +
", dog=" + dog +
'}';
}
}
pom.xml文件中添加一段配置:
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
不添加的话使用注解@ConfigurationProperties会报错
yaml配置文件:
person:
name: wangyan
age: 27
isp: true
birth: 1993/07/29
job:
name: pactera
city: beijing
classmates:
- zhang
- li
- wang
dog:
name: 果果
age: 3
映射关系:
测试文件:
package com.example.demo0211;
import com.example.demo0211.pojo.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
//单元测试
@SpringBootTest
class Demo0211ApplicationTests {
@Autowired
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
运行测试文件结果:
Person{name='wangyan', age=27, isp=true, birth=Thu Jul 29 00:00:00 CST 1993, job={name=pactera, city=beijing},
classmates=[zhang, li, wang], dog=Dog{name='果果', age=3}}
3.通过properties+@PropertySource(value="")
1.在类上添加注解:
@PropertySource(value="classpath:application.properties")
2.通过el表达式根据key获取配置文件中的值
@Value("${name}")
实体对象完整代码:
package com.example.demo0211.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
//指定读取的配置文件
@PropertySource(value="classpath:application.properties")
public class Dog {
//properties文件赋值 el表达式
@Value("${name}")
private String name;
@Value("${age}")
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
properties文件:
name=哈哈
age=4
运行结果:
运行结果中,由于name值为中文字符导致出现了乱码,这时候需要设置properties的编码。
settings-->FileEncodings 中配置:
再次运行之后不再乱码:
由此可以得知,yaml未见相比properties文件的另一个优点就是不受编码制约,即使是中文字符在没有设置编码的情况下也不会出现乱码。
4.@Value和@ConfigurationProperties对比
- cp只需要写一次即可 , value则需要每个字段都添加
- 松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定
- JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
- 复杂类型封装,yml中可以封装对象 , 使用@value就不支持JSR303数据校验
JSR303数据校验
注意:@ConfigurationProperties注解支持JSR303校验,@Value不支持。
类上添加注解@Validated
属性上按需求添加不同的校验注解
实体对象文件:
package com.example.demo0211.pojo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Email;
@Validated
@ConfigurationProperties(prefix = "cat")
@Component
public class Cat {
@Email
private String name;
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
运行结果:
其他校验:
多环境下配置文件切换
1.properties
文件命名方式:application-{profile}.properties。默认读取主配置文件application.properties中的内容,要想指定读取某一个其他的配置文件,通过指定spring.profiles.active={profile}来配置。
application.properties
server.port=8080
spring.profiles.active==dev
application-dev.properties
server.port=8081
application-uat.properties
server.port=8082
执行后结果是启动了8081的端口号。
2.yaml
通过yaml不需要每个环境创建一个配置文件,在同一个文件中就可以配置多个环境并且进行切换。
---作为分隔符分开不同环境的配置信息,spring.profiles指定环境名,spring.profiles.active指定要切换到哪个环境的配置。
server:
port: 8080
# 指定切换的环境
spring:
profiles:
active: dev
---
server:
port: 8081
# 环境名
spring:
profiles: dev
---
server:
port: 8082
# 环境名
spring:
profiles: uat
3.配置文件加载位置
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
优先级1:项目路径下的config文件夹配置文件 优先级2:项目路径下配置文件 优先级3:资源路径下的config文件夹配置文件 优先级4:资源路径下配置文件
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置;