天天看點

一個項目應對各式各樣環境-profile完美應付

作者:會寫Java的阿偉

前言

  • 一個項目能夠正常上線需要經曆各種環境的測試洗禮。面對如此多的環境我們在打包的時候也很頭疼,好在 maven能夠幫助我們巧妙地進行攜帶設定。達到不同環境設定不同的環境參數。
  • maven 中提供 profiles 支援我們多環境配置。 profiles 又分為系統配置和全局配置。所謂系統配置就是在項目的 pom.xml 中進行配置,僅對目前項目有效。而全局配置就是在 maven 的 settings.xml 中配置,當maven所有項目有效。

profiles配置

  • 這裡談論的是項目中進行配置說明了。首先在 profiles 中支援配置多個 profile , 每個 profile 除了存在一個證明環境唯一ID的 id屬性外,還可以存在 pom.xml 中其他正常的标簽。比如你可以在 profile 中放置 dependencies 來通過環境控制依賴包的引入與否。 比如你可以通過 profile 中放置 properties 來配置 pom.xml 中參數配置。

指明環境

  • 當我們系統中配置了很多個 profile 的時候而又沒有設定自動激活,這個時候我們在打包的時候就需要手動設定激活選項了。 mvn clean intsall -Pprofile1,profile2 , 這個指令說明我們選擇 profile1 和 profile2 兩套環境裡的配置和主配置結合進行打包。

預設生效

  • 相比較與指明道姓的激活方式,預設激活就顯得格外的友善了。比如公司裡有 jdk8 的項目也有 jdk11 的項目。這種情況我們每次在打包的時候再去指定激活就顯得不合适了,因為目前 java 版本 maven 是能夠擷取到的,這時候我們手動激活顯得有點雞肋了。還有些是未來可能會改動或者改動的頻率不是很大,這時候就更适合預設激活了。
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>true</activeByDefault>  
  </activation>  
  ...  
</profile>             
  • 在 settings.xml 配置檔案中除了上方在每個 profile 中選擇是否預設激活以外,還可以在最後統一選擇激活
<settings>  
  ...  
  <activeProfiles>  
    <activeProfile>local_db</activeProfile>  
  </activeProfiles>  
</settings>  
複制代碼
           

依賴檔案

  • 比如我們公司項目 jar 都是經過加密的,我們本地都是存在密鑰的。我們的加密組也為我們提供了加密程式。加密程式依賴于一份密碼本。這個時候我們打包的時候就可以通過判斷是否存在密碼本而選擇是否加載加密程式的 jar 。
  • 還有的時候我們需要判斷不存在某個檔案的時候在執行某些操作。這些 profile 都是可以幫助我們實作的。
  • 這裡的檔案路徑經過測試時相對于 pom.xml 的相對位置。你也可以填寫 絕對路徑。(僅在linux上進行了測試 , 且這裡的絕對路徑不能 ~/temp/xxxx , 必須寫 /home/zxhtom/temp/xxxx)

存在檔案

<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>  
    <file>  
      <exists>file2.properties</exists>  
    </file>  
  </activation>  
  ...  
</profile>  
複制代碼
           

不存在檔案

<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>  
    <file>  
      <missing>file2.properties</missing>  
    </file>  
  </activation>  
  ...  
</profile>  
複制代碼
           

依賴系統參數

  • 上面通過檔案進行判斷在某種場景下顯得還是不智能。 比如我現在有一個包 預設需要加載進來, 但是我想動态控制它是否加載。如果通過預設的話那麼後續我就無法更改,如果通過檔案進行控制,那麼每次我還得新增删除檔案來達到控制的效果。那麼有沒有類似于 -P 的屬性來動态控制加載呢?注意這個場景和 -P 不同的是
  • -P 是預設不加載 ,指定了就加載
  • 而我要的是 預設加載 , 指定了不加載 。 恰好跟他是相反的效果
  • 經過我翻閱資料,終于發現有這個參數可以控制,就是 property這個參數控制,這個屬性用來判斷系統參數。
  • 這個系統參數你可能有些陌生了,實際上我們經常使用 , 在打包的 時候 mvn clean install -Dhello=zxhtom 這個指令就指定了一個系統變量名叫 hello。值為 zxhtom 。這樣我們在 pom.xml 就能夠進行判斷了。

系統參數比對

  • 當存在系統變量 hello=zxhtom 時激活
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>
    <property>  
      <name>hello</name>  
      <value>zxhtom</value>  
    </property>
  </activation>  
  ...  
</profile>             
  • 當存在系統變量 hello 時激活
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>
    <property>  
      <name>hello</name>  
    </property>
  </activation>  
  ...  
</profile>             

系統參數取反

  • 上面好像還是沒法做到 預設引入依賴,通過參數動态控制依賴的效果。别着急 我們還有一個取反的功能。
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>
    <property>  
      <name>!hello</name>  
    </property>
  </activation>  
  ...  
</profile>  
           
  • 有了上面配置我們預設不存在hello 這個系統變量。則預設 dev 的 就會生效。 mvn clean intall -Dhello 這樣 dev 就不會生效了。
  • 除了 maven 打包時候需要指定參數, 有的時候我們在 idea 中運作的時候也需要設定 java -jar -Xmx2512M -Xms2512M -Dhello 諸如這樣就可以了。

依賴系統

  • 上面是我們依賴自定義設定決定 profile 的生效與否。我們還可以依賴具體的環境參數
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>  
    <os>  
      <name>Windows XP</name>  
      <family>Windows</family>  
      <arch>x86</arch>  
      <version>5.1.2600</version>  
    </os>  
  </activation>  
  ...  
</profile>             

依賴JDK

  • 還有就是我們開頭說到的,根據不同的java版本生效不同的配置
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>  
    <jdk>11</jdk>   
  </activation>  
  ...  
</profile>             

全局與局部沖突

  • -P 可以指定多個參數的 -P dev release 就可以了。而對于pom和setting,兩者是覆寫合并關系, 當指定 -P 後 會從 pom.xml 中查找 profile,然後從 settings 中 查找 profile,合并後作為最終 profile, 相同項 pom.xml 會覆寫 settings
  • 總結下來就是局部的會覆寫全局的。
  • settings.xml中的profile和pom中的profile的差別:settings.xml中的profile隻有activation,repositories,plugineReositories,properties四個子元素。通常是用來配置倉庫資訊的。