SpringBoot使用一个全局的配置文件,配置文件名application是固定的;
有以下三种文件后缀是配置文件
yaml和properties配置文件同时存在,properties配置文件的内容会覆盖yaml配置文件的内容
application.properties
application.yml
application.yaml
配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;
为了更好的编写配置文件,可以使用yaml来编写,yml和yaml后缀的文件都是使用yaml来编辑的
一、YAML(如果懂得可以略过这里)
YAML全名:YAML Ain't Markup Language
YAML A Markup Language:是一个标记语言
YAML isn't Markup Language:不是一个标记语言;
标记语言:
以前的配置文件;大多都使用的是 xxxx.xml文件;
YAML:以数据为中心,比json、xml等更适合做配置文件;
YAML语法
1.以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
2.次等级的前面必须是空格,不能使用制表符(tab)来代替空格
3.冒号之后如果有值,那么冒号和值之间至少有一个空格,不能紧贴着
1.各种值的写法
字面量:指的是(数字,字符串,布尔)
k: y
字符串默认不用加上单引号或者双引号;
- " ":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
name: "测试1 \n 测试2":
输出:测试1 (换行再输出) 测试2- ' ':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
name: "测试1 \n 测试2":
输出:测试1 \n 测试2
对象、Map(属性和值):
k: v在下一行来写对象的属性和值的关系;注意缩进
//第一种写法
person:
name: 张三
gender: 男
age: 22
//第二种写法
person: {name: 张三,gender: 男,age: 22}
数组(List,Set):
第一个值表示数组中的第一个值
//第一种写法
fruits:
- 苹果
- 桃子
- 香蕉
//第二种写法
fruits: [苹果,桃子,香蕉]
二、配置文件值的注入
在pom文件中插入以下代码,然后运行项目之后会在配置文件编写的时候有提示
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
1.编写配置文件
//YAML的写法
person:
name: 张三
gender: 男
age: 36
boss: true
birth: 1982/10/1
maps: {k1: v1,k2: v2}
lists:
- apple
- peach
- banana
dog:
name: 小狗
//properties配置文件的写法
person.name=李四
person.age=34
person.birth=1986/09/12
person.boss=true
person.gender=女
person.lists=cat,dog,pig
person.maps.k1=v1
person.maps.k2=v2
person.dog.name="小黑"
这里需要注意的是,配置文件所对应的bean文件必须在主程序类的同一包下
2.编写Person文件(并添加上get,set,tostring方法)
@ConfigurationProperties
将配置文件的每一个属性值映射到这个组件中,
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
prefix = "person" :配置文件中哪个下面的所有属性映射到本类中
而这个组件必须是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
所以必须加上@Component注解,
即这两个注解是搭配使用的
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String,Object> map;
private List<Object> list;
private Dog dog;
3.测试
package cn.clboy.helloworldquickstart;
import cn.clboy.helloworldquickstart.model.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class HelloworldquickstartApplicationTests {
@Autowired
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
结果1
测试用YAML配置文件写法的结果如下
结果2
测试中用properties配置文件的写法会出现中文会乱码,而且char类型还会抛出Failed to bind properties under 'person.gender' to java.lang.Character异常
中文乱码解决方法
在设置中找到File Encodings,将配置文件字符集改为UTF-8,并勾选:Transparent native-to-ascii conversion
三、配置文件值注入两种方式对比
配置文件值注入有两种方式:
一个是上面提到的Spring Boot的@ConfigurationProperties注解
一个是spring原先的@value注解
两种功能的比较
松散绑定:例如Person中有lastName属性,在配置文件中可以写成 lastName 或 lastname 或 last-name 或
last_name 等
SpEL:
## properties配置文件
persion.age=#{2019-1986+1}
------------------------------------------分割线---------------------------------------
# Person类
#--------------------使用@ConfigurationProperties注解,会抛出异常--------------------
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private Integer age;
#--------------------使用@value注解,没有问题--------------------
@Component
public class Person {
@Value("${person.age}")
private Integer age;
JSR303数据校验
@ConfigurationProperties支持校验,如果校验不通过,会抛出异常
@value注解不支持数据校验
复杂类型封装
@value注解无法注入map等对象的复杂类型,但list、数组可以
两种方式小结:
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,就使用@Value
如果说,我们专门编写了一个javaBean来和配置文件进行映射,就使用@ConfigurationProperties
四、注解解析
1、@PropertySource
注解的作用是加载指定的配置文件,值可以是数组,也就是可以加载多个配置文件
使用@PropertySource({"classpath:person.properties"})指定加载person.properties配置文件
需要指定加载多个配置文件时{"classpath:person.properties","classpath:person.properties"}
使用这个注解加载配置文件就需要配置类使用@component等注解而不是等待@EnableConfigurationProperties激活,而且不支持yaml,只能是properties
2、@ImportResource
@ImportResource:用于导入Spring的配置文件,让配置文件里面的内容生效;(就是以前写的springmvc.xml、applicationContext.xml)
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;想让自己写的Spring的配置文件生效加载进来;就需要吧@ImportResource标注在一个配置类上
3、@Configuration
这是SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式
配置类@Configuration ---等于---> Spring配置文件
3.1 @Bean
/***
* @Configuration
* 指明当前类是一个配置类;就是用来代替之前的Spring配置文件
* Spring配置文件中是用<bean></bean>标签来添加组件
* 而这里只需要用 @Bean
*/
@Configuration
public class MyAppConfig {
//将方法返回的值添加到容器中;容器中这个组件默认id就是方法名
@Bean
public HelloService helloService(){
System.out.println("配置类给容器中添加组件");
return new HelloService();
}
}
四、配置文件的占位符
随机的占位符
${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,65536]}
可以引用在配置文件中配置的其他属性的值,如果使用一个没有在配置文件中的属性,则会原样输出
可以使用 : 指定默认值,如果没有该属性则使用默认值
五、Profile
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境
1、多profile文件形式
文件名格式:application-{profile}.properties/yml,例如:
application-dev.properties
application-prod.properties
2、yml支持多文档块方式
每个文档块使用---分割
server:
port: 8080
spring:
profiles:
active: prod
---
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: prod
3、激活指定profile的三种方式
1、在配置文件中指定 spring.profiles.active=dev(如上)
2、项目打包后在用命令行启动时,在其命令后面带上 --spring.profiles.active=dev 即可
java -jar xxxxxxxxx.jar --spring.profiles.active=dev
3、配置虚拟机参数
-Dspring.profiles.active=dev
4、配置文件加载位置
一级(当前项目文件路径下的config文件夹下) :file: ./config/
二级( 当前项目文件路径下): file: ./
三级( 类路径下的config文件夹): classpath: /config/
四级(类路径下): classpath: /
优先级由高到底,高优先级的配置会覆盖低优先级的配置;(优先级低的先加载,后续会被优先级高的覆盖互补);
SpringBoot会从这四个位置全部加载主配置文件;并互补配置!!
这里需要注意的是,项目根路径下的配置文件在maven编译时不会打包过去,需要在pom的build标签中增加以下代码
<resources>
<resource>
<directory>.</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.yaml</include>
</includes>
</resource>
</resources>
此外还可以通过spring.config.location来改变默认的配置文件位置,(该指定的配置优先级最高)
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;java -jar xxx.jar --spring.config.location=D:/home/cloudlandboy/application.yaml
6、外部配置加载循序
SpringBoot也可以从以下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置
-
命令行参数
所有的配置都可以在命令行上进行指定,多个配置用空格分开; --配置项=值
java -jar xxx.jar --server.port=8087 --server.context-path=/abc
2.来自java:comp/env的JNDI属性
Java系统属性(System.getProperties())
操作系统环境变量
RandomValuePropertySource配置的random.*属性值
优先加载带profile(由jar包从外向内进行寻找)
- jar包外部的
application-{profile}.properties
或application.yml
(带spring.profile)配置文件- jar包内部的
application-{profile}.properties
或application.yml
(带spring.profile)配置文件
再来加载不带profile(由jar包从外向内进行寻找)
- jar包外部的
application.properties
或application.yml
(不带spring.profile)配置文件- jar包内部的
application.properties
或application.yml
(不带spring.profile)配置文件
- @Configuration注解类上的@PropertySource
- 通过SpringApplication.setDefaultProperties指定的默认属性
所有支持的配置加载来源均可查考官方文档:官方文档