1.SpringBoot配置文件类型和作用
通过上一篇可以知道
-
SpringBoot是基于约定的,所以很多配置都有默认值,
-
配置文件的作用:
- 但如果想使用自己的配置替换默认配置的话,就可以使用 application.properties或者application.yml(application.yaml)进行配置。
- SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件
2.application.yml配置文件
2.1 yml配置文件简介
- YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,
- YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导 入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。
- YML文件是以数据为核心的,比传统的xml方式更加简洁。
- YML文件的扩展名可以使用.yml或者.yaml。
2.2 yml配置文件的语法
(1)配置普通数据
语法: key:空格value
- 注意:value之前必须有一个空格,其实下面的语法中只要是键值,value前都必须有一个空格
字面量:普通的值(数字,字符串,布尔)
k: v:字面直接来写;
- 字符串默认不用加上单引号或者双引号;
- "":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
name: "zhangsan \n lisi"
输出;
zhangsan
lisi
- '':单引号;会转义特殊字符,特殊字符终只是一个普通的字符串数据
name: ‘zhangsan \n lisi’
输出;
zhangsan \n lisi
(2)配置对象数据
语法:
key:
key1: value1
key2: value2
- 使用缩进来表示层级关系,只要是左对齐的一列数据,都是同一个层级的
- 属性和值区分大小写
或者:
key: {key1: value1,key2: value2}
(3)配置Map数据
- 与上面对象的配置方式相同
(4)配置数组或集合(List、Set)数据
语法:
key:
- value1
- value2
或者:
key: [value1,value2]
示例代码演示:
我们将Person对象配置到yml文件中
Dog.java
package cn.cqu.bean;
public class Dog {
private String Name;
private Integer age;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Person.java
package cn.cqu.bean;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
@Override
public String toString() {
return "Person{" +
"lastName='" + lastName + '\'' +
", age=" + age +
", boss=" + boss +
", birth=" + birth +
", maps=" + maps +
", lists=" + lists +
", dog=" + dog +
'}';
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
application.yml
server:
port: 8082
person:
lastName: zhangsan
age: 18
boss: false
birth: 2019/9/22
maps: {k1: v1,k2: v2}
lists:
- lisi
- wangwu
-
dog:
name: 小狗
age: 2
3.yml配置文件值注入
3.1 @ConfigurationProperties
package cn.cqu.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 将配置文件中配置的每一个属性的值,映射到这个组件中
*
* @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
* prefix = "person":配置文件中哪个下面的所有属性进行一一映射
*
* 使用@Component只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
......
}
当我们使用@ConfigurationProperties后有如下警告提示
这是因为我们没有配置Configuration Annotaion处理器,它的作用是帮我们生成一些元数据信息,
通过如下打开文档:
复制如下依赖到pom.xml
其实它的作用是:我们在yml中配置的时候没有提示,导入它以后就有提示了
然后需要重新运行一下才能起作用
这下在yml文件中就有提示了,如下
使用Idea帮我们自动生成的单元测试进行测试是否注入成功
附上pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.cqu</groupId>
<artifactId>springboot_quick2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_quick2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
相同的配置,我们在properties文件中配置(将application.yml注释掉)
application.properties
#配置person的值
#此处不可以写成person.lastName
person.last-name=张三
person.age=18
person.birth=2019/9/22
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=dog
person.dog.age=15
测试结果:
可以发现虽然获取到了,但有中文乱码,这是因为对于properties文件,无论何种配置方式,Spring底层均使用Resource方式进行加载,最终基于JAVA本身的“classLoader.getResourceAsStream()”读取信息,编码默认为“ISO-8859-1”,而我们配置文件中的编码格式为utf-8
解决此问题如下:
勾选这个,Idea会在运行时会将properties文件的编码转换为ASCII,而ISO-8859-1编码向下兼容ASCII,所以便能正确读取
3.2 @Value
此注解跟我们在Spring中使用的@Value具有相同的功能
它支持三种赋值:
- 字面量
- ${key} 即从环境变量,配置文件中获取值
- #{SpEL} 即Spring的EL表达式
对Person使用@Value进行注入:
package cn.cqu.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 使用@Value来注入
*/
@Component
public class Person {
@Value("${person.lastName}")
private String lastName;
@Value("#{11*2}")
private Integer age;
@Value("true")
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
......
}
3.3 @ConfigurationProperties和@Value的比较
@ConfigurationProperties | @Value | |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
松散绑定的解释:
上述松散绑定的解释,即属性名用以下4中方式均可:(即@ConfigurationProperties以下4种方式均可,@Value必须与配置文件中相同)
- person.lastName 标准格式
- person.first-name 小写用-分割
- person.first_name 小写用_分割
- PERSON_FIRST_NAME
JSR303校验的解释:
@ConfigurationProperties支持这样的校验,@Value不支持
复杂类型的解释:
@Vaue不支持复杂类型即集合类型
那么什么时候用@Value和@ConfigurationProperties?
- 配置文件yml还是properties它们都能获取到值
- 如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
- 如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
4.@PropertySource & @ImportResource & @Bean
4.1 @PropertySource
- 作用:加载指定的配置文件
@ConfigurationProperties默认从全局配置文件(即application.yml或application.yaml或application.properties)中获取值
而当我们编写一个自己的配置文件的时候,如person.properties,就可以使用@PropertySource来加载
比如,现在将上述application.yml改成如下
而将person的信息编写在person.properties
测试:
- 可以看到值被正常加载
4.2 @ImportResource
- 作用:导入Spring的配置文件,让配置文件里面的内容生效
比如我现在在cn.cqu包下编写一个HelloService类
然后在resources目录下创建beans.xml文件
编写测试类
- 可以看到,Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上
如配置在主启动类上
再次测试
4.3 @Bean
SpringBoot推荐给容器中添加组件的方式:推荐使用全注解的方式
- 1、配置类@Configuration------>Spring配置文件
- 2、使用@Bean给容器中添加组件
我们注释掉
编写自己的配置类
package cn.cqu.config;
import cn.cqu.HelloService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Configuration 指明当前类是一个配置类,就是替代前面的Spring的配置文件beans.xml
*
*/
@Configuration
public class MyConfig {
/**
* @Bean 将方法返回值添加到容器中,容器中组件默认的id就是方法名
*/
@Bean
public HelloService helloService(){
System.out.println("配置类@Bean给容器中添加组件了");
return new HelloService();
}
}
然后进行测试
5.配置文件占位符
- 使用格式:${内容}
- 既可以用在yml文件,也可以用在properties文件
5.1 随机数
5.2 占位符获取之前配置的值,如果没有可以是用:指定默认值
6.Profile
我们可能在开发,测试,运行的时候配置文件可能发生变化,开发的时候用开发环境,项目一发布用生产环境,测试的时候用测试环境,为了方便的切换环境,Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境
6.1 多Profile文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
默认使用application.properties的配置;
比如,我在recources下创建了多个properties文件
可以看到默认使用application.properties的配置;
我们要使用其他配置文件的话,可以在application中使用spring.profiles.active来指定
当我们使用yml时,与上面是一样的
默认也为application.yml中的配置
在application.yml中添加如下配置
6.2 yml支持多文档块格式
在yml文件中使用---将文件分割为多个文档块,
- 默认执行第一个文档块,
- 当我们需要启动其他文档块的时候,需要使用spring.profiles.active来进行激活
- spring.profiles是为文档块起名字
6.3 使用命令来指定启动时使用的配置文件
方式1:配置程序参数
方式2:将项目打包,使用java命令启动
方式3:设置虚拟机参数
7.配置文件加载位置