文章内容
通常情况下,Spring Boot 在启动时会将 resources 目录下的 application.properties 或 apllication.yml 作为其默认配置文件,我们可以在该配置文件中对项目进行配置,但这并不意味着 Spring Boot 项目中只能存在一个 application.properties 或 application.yml。
除了默认配置文件,Spring Boot 还可以加载一些位于项目外部的配置文件。我们可以通过如下 2 个参数,指定外部配置文件的路径:
- spring.config.location
- spring.config.additional-location
一、默认配置文件
Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml。
1、5个默认配置文件位置
Spring Boot 启动时会扫描以下 5 个位置的 application.properties 或 apllication.yml 文件,并将它们作为 Spring boot 的默认配置文件。
- file:./config/*/
- file:./config/
- file:./
- classpath:/config/
- classpath:/
注:file: 指当前项目根目录;classpath: 指当前项目的类路径,即 resources 目录。
2、默认文件加载顺序
以上所有位置的配置文件都会被加载,且它们优先级依次降低,序号越小优先级越高。其次,位于相同位置的 application.properties 的优先级高于 application.yml。即:
classpath:/ -> classpath:/config/ -> file:./ -> file:./config/ -> file:./config/*/
所有位置的文件都会被加载,高优先级配置会覆盖低优先级配置,形成互补配置,即:
- 存在相同的配置内容时,高优先级的内容会覆盖低优先级的内容;
- 存在不同的配置内容时,高优先级和低优先级的配置内容取并集。
3、示例
创建一个名为 springbootdemo 的 Spring Boot 项目,并在当前项目根目录下、类路径下的 config 目录下、以及类路径下分别创建一个配置文件 application.yml,该项目结构如下图:
1)项目根路径下创建配置文件
项目根路径下配置文件 application.yml 配置如下:
#项目更目录下
#上下文路径为 /abc
server:
servlet:
context-path: /abc
2)项目类路径下config目录下创建配置文件
项目类路径下 config 目录下配置文件 application.yml 配置如下:
#类路径下的 config 目录下
#端口号为8084
#上下文路径为 /helloWorld
server:
port: 8084
servlet:
context-path: /helloworld
3)项目类路径下创建配置文件
项目类路径下的 application.yml 配置如下:
#默认配置
server:
port: 8080
4)创建Controller类
在 net.biancheng.www.controller 包下创建一个名为 MyController 的类,代码如下:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@ResponseBody
@RequestMapping("/test")
public String hello() {
return "hello Spring Boot!";
}
}
5)启动Spring Boot
启动 Spring Boot,查看控制台输出,如下图:
根据 Spring Boot 默认配置文件优先级进行分析:
- 该项目中存在多个默认配置文件,其中根目录下 /config 目录下的配置文件优先级最高,因此项目的上下文路径为 “/abc”;
- 类路径(classpath)下 config 目录下的配置文件优先级高于类路径下的配置文件,因此该项目的端口号为 “8084”;
- 以上所有配置项形成互补,所以访问路径为“http://localhost:8084/abc”。
6)浏览器查看结果
根据服务器端口和上下文路径,使用浏览器访问 http://localhost:8084/abc/test,结果如下图:
二、外部配置文件 – spring.config.location
1、命令行参数
我们可以先将 Spring Boot 项目打包成 JAR 文件,然后在命令行启动命令中,使用命令行参数 –spring.config.location,指定外部配置文件的路径:
java -jar {JAR} --spring.config.location={外部配置文件全路径}
需要注意的是,使用该参数指定配置文件后,会使项目默认配置文件(application.properties 或 application.yml )失效,Spring Boot 将只加载指定的外部配置文件。
2、示例
1)创建配置文件
在本地目录 D:myConfig 下,创建一个配置文件 my-application.yml,配置如下:
#指定配置文件
server:
port: 8088
2)执行MVN命令打包JAR
执行以下 mvn 命令,将 springbootdemo 项目打包成 JAR:
mvn clean package
命令执行结果如下图:
3)执行Java启动命令
打开命令行窗口,跳转到 JAR 文件所在目录,执行以下命令,其中 –spring.config.location 用于指定配置文件的新位置:
java -jar springbootdemo-0.0.1-SNAPSHOT.jar --spring.config.location=D:myConfigmy-application.yml
项目运行结果如下图:
从控制台输出可以看出:
- 服务器端口号从“8084”被修改为“8088”,表示外部配置文件已生效;
- 上下文路径则从“/abc”被修改为默认值(‘ ’),表示项目内部的默认配置文件已失效。
4)浏览器查看结果
使用浏览器访问 “http://localhost:8088/test”,结果如下图:
三、外部配置文件 – spring.config.additional-location
1、命令行参数
我们还可以在 Spring Boot 启动时,使用命令行参数 –spring.config.additional-location 来加载外部配置文件:
java -jar {JAR} --spring.config.additional-location={外部配置文件全路径}
但与 –spring.config.location 不同,–spring.config.additional-location 不会使项目默认的配置文件失效,使用该命令行参数添加的外部配置文件会与项目默认的配置文件共同生效,形成互补配置,且其优先级是最高的,比所有默认配置文件的优先级都高。
2、示例
1)打包JAR后,执行Java启动命令
将 springbootdemo 打包为 JAR 文件,打开命令行窗口,跳转到该项目 JAR 所在目录下,执行以下命令启动该项目:
java -jar springbootdemo-0.0.1-SNAPSHOT.jar --spring.config.additional-location=D:myConfigmy-application.yml
结果如下图:
2)配置文件优先级分析
注意:Maven 对项目进行打包时,位于项目根目录下的配置文件是无法被打包进项目的 JAR 包的,因此位于根目录下的默认配置文件无法在 JAR 中生效,即该项目将只加载指定的外部配置文件和项目类路径(classpath)下的默认配置文件。
它们的加载优先级顺序为:
- spring.config.additional-location 指定的外部配置文件 my-application.yml
- classpath:/config/application.yml
- classpath:/application.yml
根据配置文件优先级分析可知:
- 以上三个配置文件中 my-application.yml 的优先级最高,因此该项目的服务器端口号为 “8088”;
- 只有 classpath:/config/application.yml 中配置了上下文路径(context-path),因此该项目的上下文路径为 “/helloworld”;
- 基于以上配置分析,得出该项目访问路径为“http://localhost:8088/helloWorld”。
3)浏览器查看结果
使用浏览器访问 “http://localhost:8088/helloworld/test”,结果如下图:
4)解决根目录下配置文件无法被加载的问题
通过上面的示例,我们看到将 Spring Boot 项目打包后,然后在命令行启动命令中添加 spring.config.additional-location 参数指定外部配置文件,会导致项目根目录下的配置文件无法被加载,我们可以通过以下 3 种方式解决这个问题:
- 在 IDEA 的运行配置(Run/Debug Configuration)中,添加虚拟机参数 -Dspring.config.additional-location=D:myConfigmy-application.yml,指定外部配置文件;
- 在 IDEA 的运行配置(Run/Debug Configuration)中,添加程序运行参数 –spring.config.additional-location=D:myConfigmy-application.yml,指定外部配置文件;
- 在主启动类中调用 System.setProperty()方法添加系统属性 spring.config.additional-location,指定外部配置文件。