Maven 之 profile 與Spring boot 的 profile


一、概述

    不同的環境(測試環境、開發環境)有不同的配置,目前希望在打包的時候,就直接打出針對不同環境的包(內含有某個環境的配置)。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

https://www.cnblogs.com/lddbupt/p/5531885.html

https://www.jianshu.com/p/929b9aa70dc8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM