Spring Boot 08 - 多情境設置 maven profile 與 application.properties 進階篇
上期我們介紹完最直觀的用法,這期我們再來討論多管齊下的方向。 在開始之前,筆者總結一下上期的 Profile 的要點。 Spring boot 是經過 spring.profiles.active 去選擇什麼 (spring boot) Profile 生效 spring.profiles.active 它可以在runtime(運行時)動態更改 maven 是經過 xml 去選擇編譯時的 (maven) profile maven 編譯時為 spring.profiles.active 填入一個固定值 另外,筆者亦在測試途中,發現一個現像。 maven 並不提供混合 profile,即使下指令同時觸發兩個 profile ,最後亦只有一個 maven profile 生效。但這個部份筆者未在官方文件中找到,大家如果有任何發現,可以幫忙修正。 Spring boot 混合 Profile 當我們經IDE編譯時,可以為 spring.profiles.active 填入多個值,各值之間用逗號分隔,就可以觸發多個 profile 。 spring.profiles.active=dev,uat 程式碼中的application.properties, application-dev.properties, application-uat.properties 都會生效 Spring boot會先後載入上述三個檔案,如果有重複值,後面出現的會覆蓋前面的值。 spring.profiles.active如果填入的值與現在的application-xxx.properties不匹配,該部份不生效,例如 spring.profiles.active=dev,uat 程式碼中只有application.properties, application-dev.properties,但沒有application-uat.properties Spring boot會先後載入上述兩個檔案 上述的都好理解,當大家都接受上面的結論後,再來看這個現像。 spring.profiles.active 是啟動spring boot時,作為選擇profile的依據。 application.properties可以有一個預設的spring.profiles.active,正常跑spring boot就會看它。 正常跑spring boot時,還可以通過傳入參數--spring.profiles.active=xx,改變那個值。 Spring boot test 因為結構特殊,它只會看到 application.properties 中的那個spring.profiles.active值。 Spring boot test 暫時沒有方法傳入參數spring.profiles.active,但可以經程式碼 @ActiveProfiles 硬改運行中的 profile 。spring.profiles.active亦只會顯示 application.properties中的那個值。 Spring boot 混合 Profile 例子 大家看完概念之後,可以來看看實際例子。 當什麼都不加,就是根據application.properties的spring.profiles.active來啟動profile。 mvn clean compile spring-boot:run # or mvn clean compile package java -jar target/spring-boot-profile-0.0.1-SNAPSHOT.jar 正常spring-boot:run的情況下,可以經的 --spring.profiles.active 覆蓋過application.properties內的值。 mvn clean compile spring-boot:run -Dspring-boot.run.arguments="--spring.profiles.active=dev --spring.profiles.active=uat" mvn clean compile spring-boot:run -Dspring-boot.run.arguments="--spring.profiles.active=dev,uat" # or mvn clean compile package java -jar target/spring-boot-profile-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev --spring.profiles.active=uat java -jar target/spring-boot-profile-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev,uat 上述例子,若dev,uat內的值沒有衝突,沒有覆蓋問題。但如果有衝突,最後會是uat內定義的值。 Spring boot test Profile 例子 因為不是正常spring-boot:run,所以那些參數都沒有用,具體只會看application.properties內預設spring.profiles.active mvn clean compile test -Dspring-boot.run.arguments="--spring.profiles.active=dev,uat" # arguments will be ignored, same as mvn clean compile test Maven Profile 例子 加入Maven之後,就可以修改application.properties內的預設spring.profiles.active。但要注意,maven只會有單profile 假設pom.xml如下 application.properties如下 spring.profiles.active=@active.profile@ 下述三組例子,有且只有uat生效。因為maven的uat生效後,會修改 mvn clean compile spring-boot:run -Puat # or mvn clean compile package -Pdev -Dci=true java -jar target/spring-boot-profile-0.0.1-SNAPSHOT.jar # or mvn clean compile test -Puat 當然,你想要弄一個maven mix profile 也可以 以下例子可以令 dev, uat 同時出現在spring.profiles.active mvn clean compile spring-boot:run -Pmix # or mvn clean compile package -Pmix java -jar target/spring-boot-profile-0.0.1-SNAPSHOT.jar # or mvn clean compile test -Pmix Maven Profile Spring boot test例子 上述例子都了解後,最後就來看看全部混合的情況 當Test case中沒有硬改 profile 定義,application.properties中的spring.profiles.active就直接作用。以下情況就是同時運行dev,uat // java @SpringBootTest class ProfileTests { } // bash mvn clean compile test -Pmix 當Test case中有定義@ActiveProfiles ,application.properties中的spring.profiles.active的值會保留,但不在該test case中生效。以下情況就是同時運行uat,dev,但讀取spring.profiles.active的值會是dev,uat。 // java @SpringBootTest @ActiveProfiles(value = { "uat", "dev" }) class MultipleProfileUatDevTests { } // bash mvn clean compile test -Pmix 如果我們把maven 指令中的加入package,預期 test 執行的是 uat,dev 。而 jar 的打包結果會是 dev,uat。 // java @SpringBootTest @ActiveProfiles(value = { "uat", "dev" }) class MultipleProfileUatDevTests { } // bash mvn clean compile test package -Pmix 但請盡量不要這些做,因為會越來越混亂,特別是打包 prod 環境。為減少出錯的機會,例如test污染了prod的環境,筆者在package時,通常都會跳過test。 mvn clean compile package -Pprod -Dmaven.test.skip=true