代码下载:
试验目的:

验证springboot配置文件加载的位置和优先级

试验环境:

  • maven-3.6.0
  • win10
  • jdk8
  • springboot-2.1.6.RELEASE

一、结论说明

注意下面四个位置:

  • file:./config/
  • file:./
  • classpath:/config/
  • classpath:/

加载规则:

  1. 默认从这四个位置依次读取后缀名为properties、yml的配置文件
  2. 优先级由高到低
  3. 对于相同的属性配置,高优先级的配置会覆盖优先级低的配置
  4. 对于其他不同的属性配置,则会进行互补
  5. 优先级相同的情况下,同时有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 创建工程目录结构和文件

spring boot bean 创建优先级 springboot加载优先级_jar

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.propertiesapplication.properties的优先级要高,而server.servlet.context-path的配置是互补的

2.4 使用上面生成的jar包测试file:./config/classpath:/

jar包同目录增加两个配置文件并删除其他无用文件,最终的目录结构:

spring boot bean 创建优先级 springboot加载优先级_spring_02


增加的文件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

spring boot bean 创建优先级 springboot加载优先级_jar_03

至此, 可以看出:

  1. jar包外部的application.properties覆盖了jar里面class下的application.properties
  2. 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运行:

spring boot bean 创建优先级 springboot加载优先级_jar_04

由此可以看出自己指定的配置文件中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

spring boot bean 创建优先级 springboot加载优先级_jar包_05

由此可见:application.yml文件中的配置的应用路径覆盖了jar包里的配置,但是端口却被外面的application.properties文件覆盖。