代码下载:
试验目的:
验证springboot配置文件加载的位置和优先级
试验环境:
- maven-3.6.0
- win10
- jdk8
- springboot-2.1.6.RELEASE
一、结论说明
注意下面四个位置:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
加载规则:
- 默认从这四个位置依次读取后缀名为properties、yml的配置文件
- 优先级由高到低
- 对于相同的属性配置,高优先级的配置会覆盖优先级低的配置
- 对于其他不同的属性配置,则会进行互补
- 优先级相同的情况下,同时有application.properties和application.yml,那么application.properties里面的属性就会覆盖application.yml里的属性,因为properties比yml优先加载
注意:
[file:.]
表示的是打成的jar包的同级目录,在jar包的外部,不会被maven打到jar里去,需要自己处理位置--spring.config.location=c:\jackletter\springboot\application.properties
在运行jar包的时候可以通过上面的命令行参数指定一个配置文件(这个配置文件的优先级是最高的)
二、进行试验
2.1 创建工程目录结构和文件
2.2 代码及配置文件
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 http://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.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jackletter</groupId>
<artifactId>springboot-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-demo</name>
<description>springboot-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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
DemoApplication.java
package com.jackletter.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
TestController.java
package com.jackletter.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@RequestMapping("/test")
public String Test() {
return "hello";
}
}
src\main\resources\application.properties
server.port=8080
server.servlet.context-path=/demo
src\main\resources\config\application.properties
server.port=7070
2.3 打成jar包并运行(测试:classpath:/config/
和classpath:/
)
- 使用
mvn package
命令打包 - 控制台使用
java -jar .\springboot-demo-0.0.1-SNAPSHOT.jar
命令运行:
可以看到最终运行的端口是
7070
而路径是/demo
这就说明config/application.properties
比application.properties
的优先级要高,而server.servlet.context-path
的配置是互补的
2.4 使用上面生成的jar包测试file:./config/
和classpath:/
jar包同目录增加两个配置文件并删除其他无用文件,最终的目录结构:
增加的文件1 application.properties
server.port=6060
server.servlet.context-path=/demo2
增加的文件2 config\application.properties
server.port=5050
使用命令行运行这个jar包:java -jar .\springboot-demo-0.0.1-SNAPSHOT.jar
至此, 可以看出:
jar包外部的application.properties
覆盖了jar里面class下的application.properties
config/application.properties
覆盖application.properties
2.5 使用上面的测试环境测试--spring.config.location
在jar包外面再新建个文件another.properties
:
server.port=3030
使用命令行java -jar .\springboot-demo-0.0.1-SNAPSHOT.jar --spring.config.location=another.properties
运行:
由此可以看出自己指定的配置文件中
server.port
的配置确实覆盖了其他的文件,但是应用路径出现了点问题(好像是被覆盖了,不能认为是互补),这个问题不知是什么情况,记住轻易别用命令行这种方式。
2.6 测试application.yml和application.properties的优先级
使用上面的测试环境,在jar包目录新增文件application.yml
文件:
server:
port: 2020
servlet:
context-path: /yml
修改jar外面的application.properties
文件:
server.port=6060
命令行运行:java -jar .\springboot-demo-0.0.1-SNAPSHOT.jar
由此可见:
application.yml
文件中的配置的应用路径覆盖了jar包里的配置,但是端口却被外面的application.properties
文件覆盖。