Apache Maven 2.0 不遺餘力確保生成可移植的構建. 這意味着: 容許在POM內的構建配置, 避免全部文件系統的引用(在繼承\依賴) , 而且更嚴重地依賴本地倉庫來存儲支持該功能的元數據.html
然而, 有時移植性不是徹底可行的. 在某些特定狀況下, 插件可能須要使用本地文件系統路徑來配置. 在其餘狀況下, 可能須要一個稍微有點不一樣的依賴設置, 且該工程的名字可能須要稍微調整一下. 在其餘時候, 你可能甚至須要根據檢測到的構建環境, 在構建生命週期中包含一整個插件.linux
針對這些狀況, maven 2.0 介紹了構建配置文件的概念(build profile). 配置文件經過使用POM中的元素子集來指定(增長一個額外的section), 在多種狀況下被觸發. 配置文件在構建時修改POM, 而且爲變量設置不一樣的目標環境(例如, 在開發, 測試和產品環境中的數據庫服務器路徑). 這樣, 配置文件很容易致使不一樣成員產生不一樣的構建結果. 然而, 使用得當, 可在保留工程可移植性的同時, 使用配置文件. 這也將最少化使用 –f 操做的次數, 該操做容許用戶建立其餘不一樣參數或配置的POM, 且更加可維護, 畢竟一個工程只能有一個POM.web
類型 | 定義位置 | 路徑 |
Per Project 項目級 | POM | pom.xml |
Per User 用戶級 | Maven-settings | %USER_HOME%/.m2/settings.xml |
Global 全局 | global Maven-settings | ${maven.home}/conf/settings.xml |
Profile descriptor | project basedir | profiles.xml |
一個配置文件可經過如下方式激活:數據庫
該選項有一個參數列表: 用逗號分隔的 profile-ids. 當指定該選項時, 在參數中指定的profile將會被激活, 除了已被激活配置或 settings.xml的<activeProfiles> section激活的profiles以外.apache
mvn groupId:artifactId:goal -P profile-1,profile-2windows
運行結果是在目標目錄下, 產生了兩個文件, 它們的內容同樣.服務器
該節中包含一個<activeProfile>元素列表, 每一個包含了一個profile-id.app
在<activeProfiles>標籤下列出的 profiles將會默認地在每次工程使用它時被激活.maven
Maven的 settings.xml 文件能夠在 %USER_HOME%/.m2 目錄下找到. 若是不存在,則須要建立一個.ide
profile可根據檢測出的生成環境的狀態, 自動觸發. 這些觸發在<profile>下的<activation>一節中定義. 當前, 該檢測僅限於JDK版本的前綴匹配\ 系統屬性是否存在 或一個系統屬性的值.
(1) 當JDK的版本號以"1.4"開頭時, 下例中的配置將被觸發.
(2) Maven 2.1中也可使用範圍. 下例中表示版本 1.3, 1.4, 1.5.
注意, 右閉區間, 如: ,1.5], 也不表明包含全部的1.5版本, 由於不少狀況下會有額外的 "patch release", 例如, _05就不能包含在這個區間裏了.
(3) 系統屬性 debug, 不管取何值, 都會觸發下例.
(4) 系統屬性 enviroment 取值爲test時...
注意, 爲了觸發上例, 須要如下命令:
當文件缺失時, 就會激活:
上述配置設好後, 可以使用 mvn test 來查看 test profile 的結果. 而不是顯式的使用-p選項.
能夠用來卸載 activeByDefault 或者 經過激活配置 來激活的 profile.
咱們已經討論了在哪裏指定 profile, 以及如何激活它們. 而你能夠在一個profile裏指定什麼將會很是有用. 由於涉及 profile配置的其餘方面, 這個答案並不簡單.
依據你選擇的配置profile的方式, 你能夠得到不一樣的POM配置.
最嚴格意義上來講, 在外置文件(好比 setting.xml 或 profiles.xml)中定義的profile是不可移植的. 任何看似有高機率改變構建結果的東西, 都會被限制在POM中的嵌入profiles. 像倉庫列表之類的東西能夠簡單地做爲一個准許工程的存儲庫, 而且不會改變構建的輸出. 所以, 你只可能在settings.xml中修改 <repositories>和<pluginRepositories>節, 再加上一個額外的<properties>節.
<properties>節容許你指定 自由格式的 鍵值對, 包含在POM的插補過程當中. 這容許你經過格式${profile.provided.path} 指定一個插件配置.
另外一方面, 若是你的profiles能夠合理地在pofile內部定義, 你能夠有更多的選擇. 代價就是你只能修改那個工程和它的子模塊. 由於這些profiles 是內嵌定義的, 因此能夠更好地保持可移植性. 所以, 你能夠添加更多信息, 而避免了這些信息對其餘用戶不可用的風險.
在POM中定義profiles能夠修改如下元素:
咱們不容許修改 POM-profiles 以外的一些pom 元素. 由於這些運行時修改不會在POM部署到資源系統時分發, 形成我的的工程構建徹底不一樣於其餘人的. 另外一個緣由是POM信息有時會被父POM複用.
外部文件存儲, 好比settings.xml和profiles.xml, 也不支持 POM-profiles以外的元素. 當有效的POM文件被部署到一個遠程資源庫時, 任何人均可以獲取它的信息, 而且直接用來構建一個maven工程. 如今,假設咱們能夠在對一個構建很是重要的 dependencies 中設置 profiles, 或者其餘除POM-profiles以外的元素. 那麼最可能的是咱們不但願其餘人能從資源庫中使用POM, 甚至 構建它. 咱們也會考慮如何共享settingx.xml. 注意到太多要配置的文件是一件十分困擾的事, 並且難以維護. 底線就是, 既然這是構建數據, 它就應該放在POM中. maven 2 的一個目標就是將全部運行一個構建必須的信息都統一到一個文件中, 或者文件層次結構, 這就是POM.
隱患.
咱們已經提到過, 添加profiles到你的構建中可能會破壞工程的可移植性. 咱們更是強調了那些 profiles可能破壞工程移植性的情景.然而 , 重申這些點是值得的, 這是部分討論, 關於使用profiles時要避免的隱患.
在使用profiles時, 有兩個主要問題領域須要記住. 第一個是外部屬性, 一般在插件配置中使用. 這形成了你工程的移植風險. 另外一個, 更微妙的領域, 是一個天然的profiles的不完整規範(Incomplete Specification of a Natural Profile Set).
外部屬性定義, 是指那些在pom.xml以外定義的屬性值,但又不是定義在一個其內部相關的profile中. 在POM中, 屬性的最多見用法是插件配置. 沒有屬性, 當然可能打破項目的可移植性, 但這也可能致使構建失敗. 例如, 在一個定義在settings.xml中的profile中指定一個appserver paths, 可能致使你的集成測試插件發生失敗, 當團隊中另外一個沒有類似settings.xml的用戶企圖去構建時.
下面是一個web應用工程的pom片斷:
在你本身的本地${user.home}/.m2/settings.xml中:
當你構建 集成測試 生命週期階段時, 你的集成測試將會經過. 由於你提供的路徑容許該測試插件安裝和測試該web應用.
然而, 當你的同事嘗試去構建 集成測試時, 他的構建會完全失敗, 由於它不能處理插件配置參數<appserverPath>, 或者更糟地, 警告該參數${appserver.home}的值是無效的.
慶幸的是, 你的工程如今尚未移植. 在你的pom.xml中內聯該profile, 能夠幫助緩和該問題. 但明顯的缺點是, 每一個工程層次(容許繼承影響)如今必須指定該信息. 由於maven提供對工程繼承的良好支持, 能夠把這類配置放到團隊級POM或相似的POM中的<pluginManagement>節中, 而後簡單地繼承路徑.
另外, 不那麼具備吸引力的答案是開發環境的標準化. 然而, 這每每會損害 maven能提供的生產率.
這個profile看起來很像上一個例子中的. 有一點很重要的不一樣: 有一個面向開發環境的, 一個新的profile, 名爲 appserverConfig-dev-2, 被添加了, 而且它有一個激活section, 將會在系統屬性 env=dev-2時激活.
因此, 執行:
將會成功構建, 應用appserverConfig-dev-2 proflie.
當執行:
也會成功構建, 應用了appserverConfig-dev profile.
然而 , 執行:
不會成功構建. 爲何? 由於, ${appserver.home}的值不會是一個有效的路徑, 部署和測試你的web應用沒法進行. 咱們在編寫profiles時尚未考慮env=production的狀況. 這樣不完整的規範意味着, 咱們已經成功地根據開發環境來限制了有效的目標環境. 你的同事, 也有多是你的manager, 將不會看到這個笑話. 當你建立profiles來處理這些相似的狀況時, 必定要解決全部的target集.
用戶特定的配置文件能夠以相似的方式來進行.
肯定活動的profiles, 將幫助用戶瞭解在一次構建過程當中, 哪些特定的profiles已經被執行了. 咱們可使用maven help plugin來查詢一次構建過程當中哪些profiles是生效的.
假設, 分別在pom.xml和settings.xml中配置profile以下:
執行如下命令:
感受我翻譯得很差 =,= 理解上有點困難...因此梳理一下...
profile能夠看做是pom的一部分. 簡單來講, profile支持定義一系列的配置信息, 而後在不一樣的環境中, 能夠自動觸發不一樣的配置. 好比, 在windows下是一套配置, 在linux下是另外一套配置.
能夠選擇在多個地方定義 profile. 在不一樣地方定義, 做用範圍不一樣. 針對某個項目的配置, 能夠寫在 pom.xml中. 針對某個用戶的配置, 能夠在用戶目錄下的 .m2目錄下的 setting.xml 文件中定義. 針對全局的配置, 能夠在maven安裝目錄下的 conf目錄中的 setting.xml 文件中定義.
profile中能定義的配置信息與所處位置相關. 若是是在settings.xml中, 是全局意義的, 只能定義一些相對而言做用範圍較廣的配置, 好比<repositories>, <pluginRepositories>, <properties>. 定義在<properties>中的鍵值對能夠在pom.xml中使用.
若是是在pom.xml中, 能夠根據項目的不一樣來定義不一樣的細節配置信息. 主要有: <repositories>, <pluginRepositories>, <dependencies>, <plugins>, <properties>, <dependencyManagement>, <distributionManagement>, <build>下的子元素.
profile有多種不一樣的激活方式. 1) 在profile的<activation>下, 將<activeByDefault>元素的值設爲true, 就表示沒有指定其餘profile爲激活狀態時, 默認激活該profile. 2) 在settings.xml中使用<activeProfiles>指定自動激活的profile名. 這樣的profile在全部狀況下都處於激活狀態. 3) 顯式命令使用-p選項,指定profile. 4) 根據不一樣的環境來激活, 如jdk版本, 操做系統, 系統屬性, 5) 根據文件是否存在來激活.
可使用 mvn help: active-Profiles來查看處於激活狀態的profiles.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html