配置
SpringBoot
是基于约定的,所以很多配置都有默认值,但如果想要使用自己的配置替换默认配置的话,可以使用application.properties
或者application.yml
(application.yaml
)进行配置(配置文件名字是固定的)
.properties
配置文件通过键值对的方式进行编写:(等号两边没有空格)
server.port=8080
yml
编写配置文件的方式:(冒号和值之间是有空格的,如果不加空格,语法会报错)
server:
port: 8080
系统默认创建的配置文件是application.properties
配置文件,在根目录resources
文件夹下
我们可以在配置文件中修改系统定义的属性,如端口号server.port
(默认值是8080);也可以配置我们自定义的属性,如name
属性,但是自定义的属性配置是不会被程序自动识别的,需要我们进行手动加载,从而读取配置
如果我们在application.properties
、application.yml
和application.yaml
(这三个配置文件在同一级目录中都存在)配置文件中都配置了同样的内容,生效优先级从高到低依次是.properties
、.yml
和.yaml
(当一个属性同时存在在这些配置文件中时,低优先级的属性将被忽略掉,不会进行识别配置)
YAML
YAML
是一种直观的能够被电脑直接识别的数据序列化格式(不是一个标记语言),并且容易被人类阅读,容易和脚本语言交互,可以支持YAML
库的不同的编程语言程序导入。YAML
文件是以数据为核心的,比传统的xml
方式更加简洁
YAML
文件的拓展名可以使用.yml
或者.yaml
使用YAML
文件进行内容的配置,和xml
配置文件一样,能够体现具体的层级关系(但是写法上比xml
文件简洁)
基本语法
- 大小写敏感
- 数据值前面必须有空格,作为分隔符(否则该配置不会被识别)
- 使用缩进表示层级关系
- 缩进时不允许使用
Tab
键,只允许使用空格(各个系统Tab
对应的空格数可能不同,导致层级混乱) - 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#
表示注释,从这个字符一直到行尾,都会被解析器忽略
数据格式
YAML
语法有三种可以使用的数据格式:
对象(
map
):键值对的集合yamlperson: name: jlc # 行内写法 person: {name: jlc}
数组:一组按次序排列的值
yamladdress: - beijing - shanghai # 行内写法 address: [beijing,shanghai]
纯量:单个的、不可再分的值
yamlmsg1: 'hello \n world' # 单引号忽略转义字符 \n 会被原样的输出 msg2: "hello \n world" # 双引号识别转义字符 \n 被识别为换行 hello和world分两行输出
参数引用
YAML
文件中可以引用前面定义的参数,其引用方式为:
name: lisi
person:
name: ${name} # 引用上边定义的name值
读取配置文件内容
给定一个配置文件:
# 键值对
name: jlc
# 对象
person:
name: xiaoming
age: 25
# 数组
address:
- beijing
- shanghai
# 纯量
msg1: 'hello \n world'
SpringBoot
为我们提供了三种读取配置文件的方式:
@Value
(通过注解方式进行配置文件内容的读取)javapackage com.jlc.springbootinit; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { // 读取配置文件内容 // 键值对 @Value("${name}") // name要与配置文件中要读取内容的键一致 private String name1; // name的名称和配置文件中读取内容的键可以不同 // 对象 @Value("${person.name}") private String name2; // 数组 @Value("${address[0]}") private String address; // 纯量 @Value("${msg1}") private String msg1; @RequestMapping("/hello") public String hello() { System.out.println(name1); // jlc System.out.println(name2); // xiaoming System.out.println(address); // beijing System.out.println(msg1); // hello \n world return "Hello SpringBoot"; } }
使用
@Value
的方式获取配置文件的内容,还是比较繁琐的,不能一次性的获取所有配置信息(适合单个配置项内容的获取)Environment
(通过注入环境对象,通过该对象的方法进行配置文件内容的读取)javapackage com.jlc.springbootinit; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.core.env.Environment; @RestController public class HelloController { // 读取配置文件内容 @Autowired // 在SpringBoot启动时,就会在Spring容器中初始化Environment环境对象 private Environment env; @RequestMapping("/hello") public String hello() { System.out.println(env.getProperty("name")); // jlc System.out.println(env.getProperty("person.name")); // xiaoming System.out.println(env.getProperty("address[0]")); // beijing System.out.println(env.getProperty("msg1")); // hello \n world return "Hello SpringBoot"; } }
该方式只需注入一个对象,即可获取配置文件中的所有内容,更加简洁
@ConfigurationProperties
(通过注解,使配置文件的内容和对象进行一个绑定映射)定义一个
Person
类:javapackage com.jlc.springbootinit; import org.springframework.stereotype.Component; @Component // 该注解表示下面的Person类可以被Spring识别,是一个Bean @ConfigurationProperties(prefix = "person") // 会将配置文件中person中对应的属性值注入到当前类中,实现绑定映射 public class Person { private String name; 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; } }
测试配置文件的读取:
javapackage com.jlc.springbootinit; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.core.env.Environment; @RestController public class HelloController { // 读取配置文件内容 @Autowired private Person person; // 实例化person对象,该对象与配置文件实现了映射绑定 @RequestMapping("/hello") public String hello() { System.out.println(person); // Person{name='xiaoming', age=25} return "Hello SpringBoot"; } }
使用
@ConfigurationProperties
注解如果出现:Spring Boot Configuration Annotation Processor not fount in classpath
的警告,我们可以在pom.xml
配置文件中加上:xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
加上上述配置,我们在配置文件中编写映射绑定的对象,会有属性的提示
profile
在我们开发SpringBoot
应用时,通常同一套程序会被安装到不同的环境下,如:开发、测试和生产等。其中数据库地址、服务器端口等配置往往是不同的,如果每次打包时,都要修改配置文件,那么是比较麻烦的。
profile
功能就是来进行动态配置切换的
配置方式
多profile
文件方式
一般使用application-dev.properties
表示开发环境下的配置文件:
server.port=8081
使用application-test.properties
表示测试环境下的配置文件:
server.port=8082
使用application-pro.properties
表示生产环境下的配置文件:
server.port=8083
当我们没有去激活任意一个配置文件的配置,系统使用的是默认的端口8080
我们需要使用配置的方式去激活不同环境下的配置文件,在application.properties
主配置文件中进行激活:
spring.profiles.active=dev // 激活开发环境的配置文件
这时,运行程序,使用的端口就是在开发环境中配置的端口号8081
yml
多文档方式
使用多profile
文件方式进行配置的切换需要写不同的配置文件,使用yml
多文档方式进行配置只需写一个配置文件,将不同环境的配置划分到不同的部分即可(使用---
进行分割),创建application.yml
配置文件
---
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: test
---
server:
port: 8083
spring:
profiles: pro
---
spring:
profiles:
active: pro # 激活具体的环境配置
激活方式
配置文件
.properties
配置文件的激活方式为:spring.profiles.active=dev
.yaml
配置文件的激活方式为:
spring:
profiles:
active: pro # 激活具体的环境配置
虚拟机和命令行参数
但是通过配置文件的方式进行激活,在部署的时候,还是需要对配置文件进行修改,也是不方便的
我们可以通过虚拟机或者命令行参数来指定外部的参数
点击IDEA
左上角的SpringbootProfilesApplication
,选择Edit Configurations...
VM options
表示虚拟机参数,在虚拟机参数中指定:-Dspring.profiles.active=test
(指定使用测试环境的配置)Program arguments
表示命令行参数,在命令行参数中指定:--spring.profiles.active=test
(指定使用测试环境的配置)
使用虚拟机或者命令行参数进行配置文件的生效,使用其一种方法即可
使用命令行参数,我们可以在命令行中启动SpringBoot
程序运行的时候,指定具体的配置环境,而不需要配置文件的激活方式,在命令行输入:
java -jar .\springboot-profiles-0.0.1-SNAPSHOT.jar --spring.profiles.active=test
配置加载顺序
SpringBoot
允许我们在项目的内部进行配置文件的编写,也允许我们将配置内容写到项目的外边进行配置(如命令行参数进行配置)
内部配置的加载顺序
Springboot
程序启动时,会依次从以下位置加载配置文件(优先级从高到低为):
file:./config/
:当前项目下的/config
目录下file:./
:当前项目的根目录classpath:/config/
:classpath
的/config
目录classpath:/
:classpath
的根目录(resources
和java
文件夹在打包后会在classpath
根目录下)
高优先级配置的属性会覆盖低优先级配置的属性
config
├──application.properties // 优先级1
application.properties // 优先级2
springboot-config
├──src
│ ├── main
│ │ └── java
│ │ └── resources
│ │ ├── config
│ │ │ ├── application.properties // 优先级3
│ │ ├── application.properties // 优先级4
├──pom.xml
虽然相同的配置可能被覆盖,但是不同优先级的配置文件都会被加载
方式1和方式2的配置文件在SpringBoot
项目打包后,是不会打包到具体的jar
包中的,运行jar
包是不会识别上述两种配置的(如果需要识别,我们需要复制这个配置文件,放到与打包后的springboot-profiles-0.0.1-SNAPSHOT.jar
文件的同级目录(或者在这个同级目录中创建一个config
文件夹,在文件夹中放置配置文件),那么在运行的时候,就会自动的读取放入的配置文件的内容)
外部配置的加载顺序
外部的配置和内部的配置之间形成了一种互补的关系:如当前的项目已经写完了,并且打包好了,但是我们发现有一个配置编写错了,这个时候,我们就可以通过外部的配置进行覆盖内部的某些配置
加载外部配置的方式有很多,详细可以查看官网,常用的外部配置加载方式有(按照加载优先级从高到低为):
通过命令行参数配置:通过命令行配置修改具体的端口
javajava -jar .\springboot-profiles-0.0.1-SNAPSHOT.jar --server.port=8082
通过命令行配置可以一次性接着配置多个需要配置的内容,但是对于太多的配置内容,我们可以在外部写一个配置文件,通过命令行的方式指定这个配置文件的路径,从而读取文件中的配置信息
简单编写一个配置文件:一般使用
application.properties
:propertiesserver.port=8081 ...
通过命令行读取配置文件,并加载配置:
javajava -jar .\springboot-profiles-0.0.1-SNAPSHOT.jar --spring.config.location=d://application.properties
内部配置文件读取的方式1在
SpringBoot
项目打包后,是不会打包到具体的jar
包中的,运行jar
包是不会识别配置的(如果需要识别,我们需要在打包后的springboot-profiles-0.0.1-SNAPSHOT.jar
文件的同级目录中创建一个config
文件夹,在文件夹中放置配置文件,那么在运行的时候,就会自动的读取放入的配置文件的内容)内部配置文件读取的方式2在
SpringBoot
项目打包后,是不会打包到具体的jar
包中的,运行jar
包是不会识别配置的(如果需要识别,我们需要复制这个配置文件,放到与打包后的springboot-profiles-0.0.1-SNAPSHOT.jar
文件的同级目录,那么在运行的时候,就会自动的读取放入的配置文件的内容)