一、概述
不同的環境(測試環境、開發環境)有不同的配置,目前希望在打包的時候,就直接打出針對不同環境的包(內含有某個環境的配置)。Maven本身在 pom.xml 中就提供了 profile 標簽進行配置;
spring boot 開發的軟件,其也有不同的配置,在結合 maven 打出對應的包的時候,也需要 指定 spring.profiles.active 表示使用的是哪份配置;
二、知識點
1、maven 不同環境配置
(1) profile 的定義位置
我們可以有多個地方定義profile。定義的地方不同,它的作用范圍也不同。
- 針對於特定項目的profile配置我們可以定義在該項目的pom.xml中。
- 針對於特定用戶的profile配置,我們可以在用戶的settings.xml文件中定義profile。該文件在用戶家目錄下的“.m2”目錄下。
- 全局的profile配置。全局的profile是定義在Maven安裝目錄下的“conf/settings.xml”文件中的。
(2) profile 中能定義的信息
profile中能夠定義的配置信息跟profile所處的位置是相關的。以下就分兩種情況來討論,一種是定義在settings.xml中,另一種是定義在pom.xml中。
a) 定義在Setting.xml
當profile定義在settings.xml中時意味着該profile是全局的,它會對所有項目(文件在 Maven 安裝目錄下)或者某一用戶(文件在 用戶目錄下)的所有項目都產生作用。
此時 Setting.xml 中 profile 下可定義的標簽主要有:
- repositories
- pluginRepositories
- properties:定義在<properties>里面的鍵值對可以在pom.xml中使用
b) 定義在pom.xml中(文件在項目里面)
此時 pom.xml 中標簽主要有:
- repositories
- pluginReponsitories
- dependencies
- plugins
- properties
- dependencyManagement
- distributionManagement
(3) profile 的激活方式
a) settings.xml 中 使用 activeProfiles ,指定激活的 profile。
<profiles>
<profile>
<id>profileTest1</id>
<properties>
<hello>world</hello>
</properties>
</profile>
<profile>
<id>profileTest2</id>
<properties>
<hello>andy</hello>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>profileTest2</activeProfile> <activeProfile>profileTest1</activeProfile>
</activeProfiles>
一般情況下,activeProfiles 就定義一個 activeProfile ,但會出現如上定義了兩個,此時生效兩個 profile,pom.xml 在使用 hello 這個 property的時候,是按照 profile 定義的先后順序來進行覆蓋取值的,然后后面定義的會覆蓋前面定義的。
而在上面的這個例子中,pom.xml 中 若使用了 ${hello},表示使用 hello 的值,那么此時會使用 andy。
默認激活的 profile 在任何項目打包中都會被激活,它是全局的。
b) pom.xml 中激活方式
- activeByDefault
<profiles>
<profile>
<id>profileTest1</id>
<properties>
<hello>world</hello>
</properties>
<activation> <activeByDefault>true</activeByDefault> </activation>
</profile>
</profiles>
當執行maven 命令進行打包時,未指定 -P profile,則表示使用 activeByDefault 聲明的 profile,若使用了 嗎,mvn clean package -pl artificaId -PanotherProfile,此時就是執行指定的profile,但是settings.xml 中的 默認激活的 profile會默認一致執行,而且是先執行,后執行 pom.xml 中的 profile。
若不想默認執行settings,xml 中激活的 profile,可以使用 mvn -P !profile 命令即可。
- 根據環境來激活 profile
- 根據當前環境中的 jdk 來激活 profile
<profiles>
<profile>
<id>profileTest1</id>
<jdk>1.5</jdk> //JDK版本的前綴匹配,當JDK的版本號以"1.5"開頭時, 該配置將被觸發
</profile>
<profiles>
<profiles>
<profile>
<id>profileTest1</id>
<jdk>[1.3,1.6)</jdk> //JDK版本的前綴匹配,當JDK的版本號以"1.3\1.4\1.5"開頭時, 該配置將被觸發
</profile>
<profiles>
-
- 根據操作系統來激活profile
<profiles>
<profile>
<activation>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
</activation>
</profile>
</profiles>
-
- 基於環境變量(用戶\系統變量)
<profiles>
<profile>
<activation>
<property>
<name>debug</name> //系統屬性 debug,無論為何值,都會觸發生效該配置
</property>
</activation>
</profile>
</profiles>
<profiles>
<profile>
<activation>
<property>
<name>environment</name>
<value>test</value> //系統屬性 environment,值為test 時,會觸發生效該配置,可以使用 mvn groupId:artifactId:goal -Denvironment=test 觸發
</property>
</activation>
</profile>
</profiles>
-
- 現在\缺失 文件
<profiles>
<profile>
<activation>
<file>
<missing>target/config.xml</missing>
</file>
</activation>
</profile>
</profiles>
- 顯示使用命令激活
mvn groupId:artifactId:goal -P profile-1,profile-2
(4) 當settings.xml 和 pom.xml (本工程、從 父pom.xml 繼承下來的profile)混合用的時候生效的結果
設定場景:
- settings.xml 中 有 profile 為 test1、test2
- 父pom.xml 中有 profile 為 test1、test2、test3
- 本工程 pom.xml 中有 profile 為test1、test2、test3
- 以下表格是 maven 打包時 查找需要執行 profile 的列表,打包時 查找文件順序為:settings.xml -> 本工程pom.xml -> 父pom.xml
settings.xml | 本工程pom.xml | 父 pom.xml | mvn 打包時是否指定profile | 實際生效profile (順序 : settings.xml -> 本工程pom.xml -> 父pom.xml) |
|||
默認profile | 非默認profile | 默認profile | 非默認profile | 默認profile | 非默認profile | ||
test1 | test2 | test2 | test1、 test3、 test4 |
test3 | test1、 test2、 teset5 |
未指定 | test1、test3、test2 |
指定 test2 | test2、test2、test2 | ||||||
指定 test3 | test1、test3、test3 | ||||||
指定 test4 | test1、test4、test3 | ||||||
指定 test5 | test1、test2、test5 |
profile 生效規則如下
- 針對每份文件(settings.xml \ 本工程 pom.xml \ 父工程 pom.xml),打包時指定了 profile,若文件 中有指定的 profile 直接激活 指定的 profile,沒有則使用默認激活的 profile;
- 針對每份文件(settings.xml \ 本工程 pom.xml \ 父工程 pom.xml),打包時未指定 profile,若文件 中有默認激活的 profile 則使用默認激活的 profile,若沒有則不使用該文件中的任何 profile;
- 不同文件激活的多個 profile,出現 property 相同 key時,生效的是第一個激活profile 中的 property;
- pom.xml 中的 activeByDefault 的 profile 若定義了 dependencies ,則依賴的包在任何打包形式下都會被依賴進來;
(5)查看當前處於激活狀態的 profile
使用 mvn help:active-profiles
2、spring boot 不同環境配置
(1) 在工程中配置不同環境配置文件
其中:application.yml 內容如下
spring: application: name: web profiles: active: "@package.env@" server: port: 8090
(2) pom.xml 配置如下:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.yml</include> <include>**/*.yaml</include>
<include>**/*.properties</include> <include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.yml</exclude> <exclude>**/*.yaml</exclude>
<exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/config</directory>
<filtering>true</filtering>
<includes>
<include>**/*.yml</include> <include>**/*.yaml</include>
<include>**/*.properties</include> <include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/config</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.yml</exclude> <exclude>**/*.yaml</exclude>
<exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude>
</excludes>
</resource>
</resources>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
可以把 src/main/config 及 src/main/resources 下的配置文件 打包過程中打入。
(3) 激活
在運行的時候,傳入參數:-Dspring.profiles.active=dev,表示使用dev 環境配置;
3、不同環境配置 spring boot 與 maven結合
- application.yml 要配置成上圖所示的,spring.profiles.active=占位符屬性,占位符屬性值 在 pom.xml 中的 profile 指定
- pom.xml 中定義 profile ,如下,在本工程中定義內容:
<!-- 多環境的不同配置,在運行時需指明使用哪個環境配置 -->
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault> <!-- 運行時未指明 profile,則使用默認的,該配置表示 dev為默認配置 -->
</activation>
<properties>
<package.env>dev</package.env>
</properties>
</profile>
<profile>
<id>release</id>
<properties>
<package.env>release</package.env>
</properties>
</profile>
</profiles>
- pom.xml 中的 resource 標簽若沒有上面的示例配置復雜,也一定要有以下內容,才能讓 maven 將其 property 寫入到指定的配置文件中。
<resource>
<directory>src/main/resources</directory> // 需要將 maven 的 property 寫入 src/main/resources 下所有的配置文件中(只要該配置文件中使用了propetry對應的占位符,如上面 application.yml 配置的那樣
<filtering>true</filtering>
</resource>
- 激活
此時,執行命令:mvn groupId:artifactId:goal -P dev 時,maven 的 dev profile 生效,其中定義的 package.env 屬性值為dev,此時打開 target 下的 application.yml,其內容已變成,如下:
spring: application: name: web profiles: active: "dev" server: port: 8090
問題:
在做上述例子的時候,發現按照如上配置之后,執行mvn命令,打開 target 下的 application.yml @package.dev@ 還是沒有替換成對應值,該原因為:
- maven 默認可識別的配置文件占位符 符號為 ${};
- 若 pom.xml 有通過 parent 標簽繼承別的 pom.xml ,此時需打開父pom.xml 查看,如,本實例繼承了 spring boot 的pom.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
</parent>
因此 spring boot 繼承過來的這種形式,配置文件中要使用 @ 作為占位符,但是若是使用 dependency 這種方式繼承 spring boot 的話,直接使用 ${},作為占位符即可。
PS: 以上參考內容:
https://www.cnblogs.com/wxgblogs/p/6696229.html