構建項目時可能會遇到在測試(如單元測試)、開發、模擬、生產等不一樣環境下須要不一樣配置(properties、xml)或資源(jpg、png、mp3)的狀況。好比常見的數據庫鏈接(即 jdbc url)的值,在不一樣的環境下可能有以下幾種值: mysql
或者一樣是生產環境,針對(產品)交付給A公司客戶的與交付給B公司客戶的須要不一樣配置或者資源,好比產品界面中的公司名稱、公司LOGO等。 sql
又或者針對不一樣的操做系統(如 Windows,Linux)須要爲某個配置設定不一樣的文件路徑。 shell
可見,在不一樣的軟件開發生命週期階段、不一樣的最終客戶(用戶)環境、不一樣的運行平臺都有可能須要不一樣配置或資源的狀況。假如各個環境下的差異很小的話,咱們能夠在項目編譯以後手工修改或者寫個 shell script 自動修改,但若是須要修改的項目不少並且複雜的話,則應該使用 Apache Maven 的 Profile 和 Filtering 功能來解決。(固然前提是你的項目必須是用 Maven 構建的啦,哈哈,還有測試階段所使用到的資源文件實際上 Maven 默認已經劃分出來,因此並不須要本文所說的方法) 數據庫
Filtering 是 Maven Resources Plugin 的一個功能,它會使用系統屬性或者項目屬性的值替換資源文件(*.properties,*.xml)當中 ${…} 符號的值。好比你係統屬性有一項 「user.name=foobar」,那麼資源文件當中的 ${user.name} 符號會在 Maven 編譯時自動被替換爲 「foobar」。 apache
舉個例子: bash
默認的項目資源文件位於 「src/main/resources」 目錄,在該目錄下建立一個文件 「test.properties」,裏面寫上一行: maven
Hello ${user.name} 單元測試
而後修改項目文件(pom.xml)啓用 filtering 功能,如: 測試
<project> ... <build> ... <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> ... </resources> ... </build> ... </project> |
而後編譯項目: ui
$mvn clean compile -Duser.name=foobar |
查看輸出文件 target/classes/test.properties 的內容,可見原先的 「Hello {user.name}」 已經變成 「Hello foobar」。
咱們也能夠把 filtering 用到的變量寫在項目屬性段裏,好比:
<project> ... <properties> <user.name>foobar</user.name> <user.email>foobar@some.com</user.email> </properties> ... </project> |
若是屬性項比較多的話,最佳實踐是把他們抽離出來獨立一個屬性文件,好比在你項目目錄(即 pom.xml 文件所在的目錄)新建一個屬性文件 project.properties:
user.name=foobar user.email=foobar@some.com |
而後在 build/filters/filter 裏指明使用這個屬性文件做爲 filtering 屬性值的來源:
<project> ... <build> ... <filters> <filter>project.properties</filter> </filters> ... </build> ... </project> |
Profile 的做用是容許你在項目文件(pom.xml)裏定義若干個 profile 段,而後在編譯時選擇其中的一個用於覆蓋項目文件原先的定義。接着上一個例子,若是咱們須要爲開發環境和生產環境定義不一樣的 user.name 屬性值,則咱們在項目目錄裏建立兩個屬性文件:
profile-development.properties,內容
user.name=foobar |
profile-production.properties,內容
user.name=tom |
而後在項目文件(pom.xml)裏增長 profile 段,以下:
<project> ... <profiles> <profile> <id>development</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <filters> <filter>profile-development.properties</filter> </filters> </build> </profile> <profile> <id>production</id> <build> <filters> <filter>profile-production.properties</filter> </filters> </build> </profile> </profiles> </project> |
在編譯項目時,可使用 -P 參數指定須要使用的 profile 的 id,好比下面命令將會使用 development profile:
$mvn clean compile -Pdevelopment |
若是想使用 production profile 則執行以下命令:
$mvn clean compile -Pproduction |
假如不指定 -P 參數的話,則會使用 activeByDefault=true 的一項(即 development)。
至此,經過 filtering 和 profile 功能實現了爲開發環境和生產環境使用不一樣配置值的目的。固然 profile 還能夠容許你添加更多的定義,好比爲某一個 profile 添加不一樣的資源文件。在一些大中型項目裏,不一樣的環境可能僅僅修改配置值並不足夠,可能還須要某個配置文件整個替換,那麼就應該在 profiles/profile/build/resources 段裏指定了。詳細的能夠參閱附錄連接。