上一節:springboot開發筆記-(7)-Profile多環境配置文件加載html
server.servlet.context-path=/app server.port=8888 spring.config.location=xxx/xxx/application.properties下面本文中說到
"級別高"
意思就是會替換其餘的, 以它爲首選, 它最終會起做用, 其餘的會被覆蓋;java
本節要回答的問題:springboot應用部署後, 配置文件以哪一個爲準? 假如應用打包成可執行app.jar後有如下這幾個配置文件:web
->官網稱此爲: file:./config/
->官網稱此爲: file:./config/
->官網稱此爲: classpath:/
->官網稱此爲: classpath:/config/
java -jar app.jar --server.port=9999
來指定;spring.config.location=xxx
來指定; (注意: 這個配置實測會互補
失效--即: 只有它本身起做用)--let's guess:spring
咱們先來作一個猜想, 若是是讓咱們本身設計, 想象實際上線的場景, 咱們會指望哪一個優先級最高(最終會覆蓋其餘配置的)?shell
若是我在線上部署了一個app.jar文件, 執行
java -jar app.jar
啓動應用; 啓動以後線上若是有問題了, 好比端口被佔用, 好比數據庫配置修改, 我須要立刻調整一個參數, 最快的方式是什麼?數據庫
- 首先: 直接重啓,
java -jar app.jar --some.prop=new_value
確定是這個最快, 或者乾脆本身指定一個配置文件的地址, --參數加命令行後面; (上面5/6)- 除了執行帶參數, 方便修改的確定是 jar平級目錄下了, 那麼, 應該輪到 app.jar平級目錄下的配置了:
是設置哪一個級別高呢? 直接讀取application.properties? 仍是 config/application.properties? apache
有的人認爲 config很直觀, 就把它下面的設爲高級別---沒錯---springboot的設計者就是這類的(上面2);json
- 固然 緊接着就是平級的了(上面1)
- 因此jar包裏面的兩處, 應該是低級別的了, 按照第2點的邏輯, 應該是 classpath:/config/application.properties 級別高於 classpath:application.properties;
因此咱們就大概出來一個思路, 配置起做用優先級別依次是:segmentfault
啓動時指定某些參數tomcat
java -jar app.jar --server.port=9999
啓動時指定配置文件(有坑~)
java -jar app.jar -spring.config.location=/mydir/application.properties
jar同目錄的config/application.properties
app.jar 同級別目錄下的 ./config/application.properties
jar同目錄的application.properties
app.jar同級別目錄下的 application.properties
jar內部 classpath目錄下的 ./config/application.properties
app.jar/BOOT-INF/classes/config/application.properties
jar內部classpath目錄下的 application.properties
app.jar/BOOT-INF/classes/application.properties
注意: 2處之因此說有坑是由於:
- 其餘的配置文件只是優先級不一樣, 全部的配置文件還都是能夠加載互補的, 只是優先級更高的會覆蓋優先級低的
- 可是2處這個慫配置則否則: 假如你指定了 -spring.config.location=xxx , 你要當心了, 這至關因而個渣男: 他只顧本身, 不和其餘的互補, 別的都被忽略了!!!
springboot-02-config
, 建立了4個配置文件, 配置對應關係如圖:
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 https://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.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.niewj</groupId> <artifactId>springboot-02-config</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-02-config</name> <description>springboot-2-config</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
person.java
package com.niewj.springboot.model; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.List; /**
*/
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private Integer age; private String lastName; private boolean student; private String location; private List<String> hobbies;
}
4. controller:
package com.niewj.springboot.controller;
import com.niewj.springboot.model.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by niewj on 2020/8/5 23:17 */
@RestController
public class HelloController {
@Autowired private Person person; @RequestMapping("/hello") public Object hello(){ return person; }
}
### 8.2.2 執行流程 1. 編譯打包 > mvn clean install -Dmaven.test.skip=true 2. 打包後生成一個 `app.jar`可執行文件 3. `show in explore` 進入 app.jar所在目錄, 咱們選擇把jar包複製到其餘目錄, 好比: E:/deploy/app.jar 4. 目錄下`shift+右鍵->在此處打開命令行窗口` >config(目錄下有application.properties) >app.jar >application.properties 5. 在命令行`java -jar app.jar`
PS E:deploy> java -jar .app.jar
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )__ | ' | '_| | '_ / _` | \
\\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.2.RELEASE)
2020-08-06 13:23:53.011 INFO 20304 --- [ main] com.niewj.springboot.ConfigApplication : Starting ConfigApplication v0.0.1-SNAPSHOT on LAPTOP-7EINAF4M with PID 20304 (E:deployapp.jar started by niewj in E:deploy)
2020-08-06 13:23:53.015 INFO 20304 --- [ main] com.niewj.springboot.ConfigApplication : No active profile set, falling back to default profiles: default
2020-08-06 13:23:56.206 INFO 20304 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8004 (http)
2020-08-06 13:23:56.225 INFO 20304 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-06 13:23:56.226 INFO 20304 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29]
2020-08-06 13:23:56.343 INFO 20304 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-06 13:23:56.343 INFO 20304 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3275 ms
2020-08-06 13:23:56.512 INFO 20304 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-06 13:23:56.721 INFO 20304 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8004 (http) with context path ''
2020-08-06 13:23:56.724 INFO 20304 --- [ main] com.niewj.springboot.ConfigApplication : Started ConfigApplication in 4.112 seconds (JVM running for 4.652)
能夠看到, 使用的是端口: `8004 `, 再經過 http://localhost:8004/hello 訪問, 顯示:
{"age":30,"lastName":"wj","student":false,"location":"file/config/application.properties","hobbies":["8004","running","coding","cooking"]}
--> 可見起做用的是: `app.jar同目錄下的 config/application.properties` 6. 咱們刪掉這個目錄再試一次:
PS E:deploy> java -jar .app.jar
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )__ | ' | '_| | '_ / _` | \
\\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.2.RELEASE)
2020-08-06 13:27:45.312 INFO 7716 --- [ main] com.niewj.springboot.ConfigApplication : Starting ConfigApplication v0.0.1-SNAPSHOT on LAPTOP-7EINAF4M with PID 7716 (E:deployapp.jar started by niewj in E:deploy)
2020-08-06 13:27:45.315 INFO 7716 --- [ main] com.niewj.springboot.ConfigApplication : No active profile set, falling back to default profiles: default
2020-08-06 13:27:48.470 INFO 7716 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8003 (http)
2020-08-06 13:27:48.482 INFO 7716 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-06 13:27:48.483 INFO 7716 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29]
2020-08-06 13:27:48.591 INFO 7716 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-06 13:27:48.592 INFO 7716 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3227 ms
2020-08-06 13:27:48.754 INFO 7716 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-06 13:27:48.954 INFO 7716 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8003 (http) with context path ''
2020-08-06 13:27:48.957 INFO 7716 --- [ main] com.niewj.springboot.ConfigApplication : Started ConfigApplication in 4.081 seconds (JVM running for 4.606)
能夠看到, 使用的是端口: `8003`, 再經過 http://localhost:8003/hello 訪問, 顯示:
{"age":30,"lastName":"wj","student":false,"location":"file/application.properties","hobbies":["8003","running","coding","cooking"]}
--> 可見起做用的是: `app.jar同目錄下的 ./application.properties` 7. 刪掉./application.properties再試:
PS E:deploy> java -jar .app.jar
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )__ | ' | '_| | '_ / _` | \
\\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.2.RELEASE)
2020-08-06 13:31:42.852 INFO 3700 --- [ main] com.niewj.springboot.ConfigApplication : Starting ConfigApplication v0.0.1-SNAPSHOT on LAPTOP-7EINAF4M with PID 3700 (E:deployapp.jar started by niewj in E:deploy)
2020-08-06 13:31:42.855 INFO 3700 --- [ main] com.niewj.springboot.ConfigApplication : No active profile set, falling back to default profiles: default
2020-08-06 13:31:46.018 INFO 3700 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8002 (http)
2020-08-06 13:31:46.032 INFO 3700 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-06 13:31:46.033 INFO 3700 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29]
2020-08-06 13:31:46.144 INFO 3700 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-06 13:31:46.145 INFO 3700 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3239 ms
2020-08-06 13:31:46.306 INFO 3700 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-06 13:31:46.509 INFO 3700 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8002 (http) with context path ''
2020-08-06 13:31:46.514 INFO 3700 --- [ main] com.niewj.springboot.ConfigApplication : Started ConfigApplication in 4.051 seconds (JVM running for 4.579)
能夠看到, 使用的是端口: `8002`, 再經過 http://localhost:8002/hello 訪問, 顯示:
{"age":30,"lastName":"wj","student":false,"location":"resource/config/application.properties","hobbies":["8002","running","coding","cooking"]}
--> 可見起做用的是: `app.jar包內的classpath目錄下的: classpath:config/application.properties` 8. 到此就不用再試了, 若是沒有config目錄, 確定讀取的是classpath: application.properties了, 這個咱們平時用的就是它; 正好證明了上面的結論. 9. 咱們再試試 `spring.config.location`命令行指定配置文件的執行方式: 在桌面上放了一個 application.properties, 內容以下:
server.port=8333 person.hobbies=8333,running,coding,cooking person.location=spring.config.location/application.properties ```
java -jar app.jar --spring.config.location=C:\Users\weiju\Desktop\application.properties
PS E:\deploy> java -jar app.jar --spring.config.location=C:\Users\weiju\Desktop\application.properties . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.2.RELEASE) 2020-08-06 13:39:40.251 INFO 20548 --- [ main] com.niewj.springboot.ConfigApplication : Starting ConfigApplication v0.0.1-SNAPSHOT on LAPTOP-7EINAF4M with PID 20548 (E:\deploy\app.jar started by niewj in E:\deploy) 2020-08-06 13:39:40.254 INFO 20548 --- [ main] com.niewj.springboot.ConfigApplication : No active profile set, falling back to default profiles: default 2020-08-06 13:39:43.357 INFO 20548 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8333 (http) 2020-08-06 13:39:43.368 INFO 20548 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2020-08-06 13:39:43.368 INFO 20548 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29] 2020-08-06 13:39:43.452 INFO 20548 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2020-08-06 13:39:43.453 INFO 20548 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3142 ms 2020-08-06 13:39:43.615 INFO 20548 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2020-08-06 13:39:43.805 INFO 20548 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8333 (http) with context path '' 2020-08-06 13:39:43.809 INFO 20548 --- [ main] com.niewj.springboot.ConfigApplication : Started ConfigApplication in 3.997 seconds (JVM running for 4.531)
能夠看到, 使用的是端口: `8333`, 再經過 http://localhost:8333/hello 訪問, 顯示: ```json {"age":null,"lastName":null,"student":false,"location":"spring.config.location/application.properties","hobbies":["8333","running","coding","cooking"]} ``` --> 一樣: 證實了渣男屬性 `spring.config.location` : 只顧本身, 別人都拋棄了, 沒有了`互補`功能;
須要注意的幾點:
- 咱們能夠看到他們之間除了優先級, 其餘的是都加載的, 是互補的關係(命令行帶參spring.config.properties除外)
- 上面的測試, 除了刪除以外, 更名也生效, 名字不是 application.properties/application.yml都不會認的;
- 咱們沒有試命令行指定某個參數, 好比
java -jar app.jar --server.port=8080
這個; 它是第一優先級!
4.2.3. Application Property Files
SpringApplication
loads properties fromapplication.properties
files in the following locations and adds them to the SpringEnvironment
:
- A
/config
subdirectory of the current directory- The current directory
- A classpath
/config
package- The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
......
Config locations are searched in reverse order. By default, the configured locations are
classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/
. The resulting search order is the following:
file:./config/
file:./config/*/
file:./
classpath:/config/
classpath:/
優先級高的會覆蓋低的, 也能夠理解他們的加載時機是順序相反的!
java -jar app.jar --server.port=9999
啓動時指定配置文件(有坑:互補失效!)
java -jar app.jar -spring.config.location=/mydir/application.properties
jar同目錄的config/application.properties
app.jar 同級別目錄下的 ./config/application.properties
jar同目錄的application.properties
app.jar同級別目錄下的 application.properties
jar內部 classpath目錄下的 ./config/application.properties
app.jar/BOOT-INF/classes/config/application.properties
jar內部classpath目錄下的 application.properties
app.jar/BOOT-INF/classes/application.properties