概念
什么是Maven
Maven 是 Apache 軟件基金會組織維護的一款自動化構建工具,專注服務于 JAVA 平臺的項目構建和依賴管理。Maven 這個單詞的本意是:專家,內行。讀音是[‘me?v(?)n]或[‘mevn]。
什么是構建
構建并不是創建,創建一個工程并不等于構建一個項目。要了解構建的含義我們應該由淺入深的從以下三個層面來看:
純 Java 代碼
大家都知道,我們 Java 是一門編譯型語言,.java 擴展名的源文件需要編譯成.class 擴展名的字節碼文件才能夠執行。所以編寫任何 Java 代碼想要執行的話就必須經過編譯得到對應的.class 文件。
Web 工程
當我們需要通過瀏覽器訪問 Java 程序時就必須將包含 Java 程序的 Web 工程編譯的結果“拿”到服務器上的指定目錄下,并啟動服務器才行。這個“拿”的過程我們叫部署。
我們可以將未編譯的 Web 工程比喻為一只生的雞,編譯好的 Web 工程是一只煮熟的雞,編譯部署的過程就是將雞燉熟。
Web 工程和其編譯結果的目錄結構對比見下圖:
實際項目
在實際項目中整合第三方框架,Web 工程中除了 Java 程序和 JSP 頁面、圖片等靜態資源之外,還包括第三方框架的 jar 包以及各種各樣的配置文件。所有這些資源都必須按照正確的目錄結構部署到服務器上,項目才可以運行。所以綜上所述:構建就是以我們編寫的 Java 代碼、框架配置文件、國際化等其他資源文件、JSP 頁面和圖片等靜態資源作為“原材料”,去“生產”出一個可以運行的項目的過程。
那么項目構建的全過程中都包含哪些環節呢?
構建的幾個過程
- 清理:刪除以前的編譯結果,為重新編譯做好準備。
- 編譯:將 Java 源程序編譯為字節碼文件。
- 測試:針對項目中的關鍵點進行測試,確保項目在迭代開發過程中關鍵點的正確性。
- 報告:在每一次測試后以標準的格式記錄和展示測試結果。
- 打包:將一個包含諸多文件的工程封裝為一個壓縮文件用于安裝或部署。Java 工程對應 jar 包,Web工程對應 war 包。
- 安裝:在 Maven 環境下特指將打包的結果——jar 包或 war 包安裝到本地倉庫中。
- 部署:將打包的結果部署到遠程倉庫或將 war 包部署到服務器上運行。
什么是自動化構建
其實上述環節我們在 Eclipse 中都可以找到對應的操作,只是不太標準。那么既然 IDE 已經可以進行構建了我們為什么還要使用 Maven 這樣的構建工具呢?我們來看一個小故事:
- 這是陽光明媚的一天。托馬斯向往常一樣早早的來到了公司,沖好一杯咖啡,進入了自己的郵箱——很不幸,QA 小組發來了一封郵件,報告了他昨天提交的模塊的測試結果——有 BUG。“好吧,反正也不是第一次”,托馬斯搖搖頭,進入 IDE,運行自己的程序,編譯、打包、部署到服務器上,然后按照郵件中的操作路徑進行測試。“嗯,沒錯,這個地方確實有問題”,托馬斯說道。于是托馬斯開始嘗試修復這個 BUG,當他差不多有眉目的時候已經到了午飯時間。
- 下午繼續工作。BUG 很快被修正了,接著托馬斯對模塊重新進行了編譯、打包、部署,測試之后確認沒有問題了,回復了 QA 小組的郵件。
- 一天就這樣過去了,明媚的陽光化作了美麗的晚霞,托馬斯卻覺得生活并不像晚霞那樣美好啊。
讓我們來梳理一下托馬斯這一天中的工作內容
從中我們發現,托馬斯的很大一部分時間花在了“編譯、打包、部署、測試”這些程式化的工作上面,而真正需要由“人”的智慧實現的分析問題和編碼卻只占了很少一部分。
能否將這些程式化的工作交給機器自動完成呢?——當然可以!這就是自動化構建。
此時 Maven 的意義就體現出來了,它可以自動的從構建過程的起點一直執行到終點:
為什么要選擇Maven
真的需要嗎?
傳統的Web開發即使不使用 Maven 我們仍然可以進行 B/S 結構項目的開發。從表述層、業務邏輯層到持久化層再到數據庫都有成熟的解決方案。
Maven 并不是直接用來輔助編碼的,它戰斗的崗位并不是以上各層。所以我們有必要通過企業開發中的實際需求來看一看哪些方面是我們現有技術的不足。
為什么需要?
添加第三方 jar 包
在今天的 JavaEE 開發領域,有大量的第三方框架和工具可以供我們使用。要使用這些 jar 包最簡單的方法就是復制粘貼到 WEB-INF/lib 目錄下。但是這會導致每次創建一個新的工程就需要將 jar 包重復復制到 lib 目錄下,從而造成工作區中存在大量重復的文件,讓我們的工程顯得很臃腫。
而使用 Maven 后每個 jar 包本身只在本地倉庫中保存一份,需要 jar 包的工程只需要以坐標的方式簡單的引用一下就可以了。不僅極大的節約了存儲空間,讓項目更輕巧,更避免了重復文件太多而造成的混亂。
jar 包之間的依賴關系
jar 包往往不是孤立存在的,很多 jar 包都需要在其他 jar 包的支持下才能夠正常工作,我們稱之為
jar 包之間的依賴關系。最典型的例子是:commons-fileupload-1.3.jar 依賴于 commons-io-2.0.1.jar,如果沒有 IO 包,FileUpload 包就不能正常工作。
那么問題來了,你知道你所使用的所有 jar 包的依賴關系嗎?當你拿到一個新的從未使用過的 jar 包,你如何得知他需要哪些 jar 包的支持呢?如果不了解這個情況,導入的 jar 包不夠,那么現有的程序將不能正常工作。再進一步,當你的項目中需要用到上百個 jar 包時,你還會人為的,手工的逐一確認它們依賴的其他 jar 包嗎?這簡直是不可想象的。
而引入 Maven 后,Maven 就可以替我們自動的將當前 jar 包所依賴的其他所有 jar 包全部導入進來,無需人工參與,節約了我們大量的時間和精力。用實際例子來說明就是:通過 Maven 導入 commons-fileupload-1.3.jar 后,commons-io-2.0.1.jar 會被自動導入,程序員不必了解這個依賴關系。
下圖是 Spring 所需 jar 包的部分依賴關系
獲取第三方 jar 包
JavaEE 開發中需要使用到的 jar 包種類繁多,幾乎每個 jar 包在其本身的官網上的獲取方式都不盡相同。為了查找一個 jar 包找遍互聯網,身心俱疲,沒有經歷過的人或許體會不到這種折磨。不僅如此,費勁心血找的 jar 包里有的時候并沒有你需要的那個類,又或者又同名的類沒有你要的方法——以不規范的方式獲取的 jar 包也往往是不規范的。
使用 Maven 我們可以享受到一個完全統一規范的 jar 包管理體系。你只需要在你的項目中以坐標的方式依賴一個 jar 包,Maven 就會自動從中央倉庫進行下載,并同時下載這個 jar 包所依賴的其他 jar 包
——規范、完整、準確!一次性解決所有問題!
Tips:在這里我們順便說一下,統一的規范幾乎可以說成是程序員的最高信仰。如果沒有統一的規范,就意味著每個具體的技術都各自為政,需要以諸多不同的特殊的方式加入到項目中;好不容易加入進來還會和其他技術格格不入,最終受苦的是我們。而任何一個領域的統一規范都能夠極大的降低程序
員的工作難度,減少工作量。例如:USB 接口可以外接各種設備,如果每個設備都有自己獨特的接口,那么不僅制造商需要維護各個接口的設計方案,使用者也需要詳細了解每個設備對應的接口,無疑是非常繁瑣的。
將項目拆分成多個工程模塊
隨著 JavaEE 項目的規模越來越龐大,開發團隊的規模也與日俱增。一個項目上千人的團隊持續開發很多年對于 JavaEE 項目來說再正常不過。那么我們想象一下:幾百上千的人開發的項目是同一個 Web 工程。那么架構師、項目經理該如何劃分項目的模塊、如何分工呢?這么大的項目已經不可能通過 package 結構來劃分模塊,必須將項目拆分成多個工程協同開發。
多個模塊工程中有的是 Java 工程,有的是 Web 工程。那么工程拆分后又如何進行互相調用和訪問呢?這就需要用到 Maven 的依賴管理機制。大家請看我們的 Survey 調查項目拆分的情況:
上層模塊依賴下層,所以下層模塊中定義的 API 都可以為上層所調用和訪問。
怎樣使用Maven
Maven 的核心程序中僅僅定義了抽象的生命周期,而具體的操作則是由 Maven 的插件來完成的。可是 Maven 的插件并不包含在 Maven 的核心程序中,在首次使用時需要聯網下載。
下載得到的插件會被保存到本地倉庫中。本地倉庫默認的位置是:~.m2repository。(也可以自定義倉庫)
如果不能聯網可以使用我們提供的 RepMaven.zip 解壓得到。具體操作參見“Maven 操作指南.txt”。
Maven核心概念
本章節將詳細地梳理Maven的核心概念和功能點。
- Maven 核心概念
- Maven 能夠實現自動化構建是和它的內部原理分不開的,這里我們從 Maven 的九個核心概念入手,看看 Maven 是如何實現自動化構建的。
- POM
- 約定的目錄結構
- 坐標
- 依賴管理
- 倉庫管理
- 生命周期
- 插件和目標
- 繼承
- 聚合
概念
- Project Object Model:項目對象模型。將 Java 工程的相關信息封裝為對象作為便于操作和管理的模型。Maven 工程的核心配置。可以說學習 Maven 就是學習 pom.xml 文件中的配置。
POM.XML解讀
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
<!-- 父項目的坐標。如果項目中沒有規定某個元素的值,那么父項目中的對應值即為項目的默認值。 坐標包括group ID,artifact ID和 version。 -->
<parent>
<!-- 被繼承的父項目的構件標識符 -->
<artifactId />
<!-- 被繼承的父項目的全球唯一標識符 -->
<groupId />
<!-- 被繼承的父項目的版本 -->
<version />
<!-- 父項目的pom.xml文件的相對路徑。相對路徑允許你選擇一個不同的路徑。默認值是../pom.xml。Maven首先在構建當前項目的地方尋找父項目的pom,其次在文件系統的這個位置(relativePath位置),然后在本地倉庫,最后在遠程倉庫尋找父項目的pom。 -->
<relativePath />
</parent>
<!-- 聲明項目描述符遵循哪一個POM模型版本。模型本身的版本很少改變,雖然如此,但它仍然是必不可少的,這是為了當Maven引入了新的特性或者其他模型變更的時候,確保穩定性。 -->
<modelVersion> 4.0.0 </modelVersion>
<!-- 項目的全球唯一標識符,通常使用全限定的包名區分該項目和其他項目。并且構建時生成的路徑也是由此生成, 如com.mycompany.App生成的相對路徑為:/com/mycompany/app -->
<groupId> asia.banseon </groupId>
<!-- 構件的標識符,它和group ID一起唯一標識一個構件。換句話說,你不能有兩個不同的項目擁有同樣的artifact ID和groupID;在某個特定的group ID下,artifact ID也必須是唯一的。構件是項目產生的或使用的一個東西,Maven為項目產生的構件包括:JARs,源碼,二進制發布和WARs等。 -->
<artifactId> banseon-maven2 </artifactId>
<!-- 項目產生的構件類型,例如jar、war、ear、pom。插件可以創建他們自己的構件類型,所以前面列的不是全部構件類型 -->
<packaging> jar </packaging>
<!-- 項目當前版本,格式為:主版本.次版本.增量版本-限定版本號 -->
<version> 1.0-SNAPSHOT </version>
<!-- 項目的名稱, Maven產生的文檔用 -->
<name> banseon-maven </name>
<!-- 項目主頁的URL, Maven產生的文檔用 -->
<url> http://www.baidu.com/banseon </url>
<!-- 項目的詳細描述, Maven 產生的文檔用。 當這個元素能夠用html格式描述時(例如,CDATA中的文本會被解析器忽略,就可以包含HTML標簽), 不鼓勵使用純文本描述。如果你需要修改產生的web站點的索引頁面,你應該修改你自己的索引頁文件,而不是調整這里的文檔。 -->
<description> A maven project to study maven. </description>
<!-- 描述了這個項目構建環境中的前提條件。 -->
<prerequisites>
<!-- 構建該項目或使用該插件所需要的Maven的最低版本 -->
<maven />
</prerequisites>
<!-- 項目的問題管理系統(Bugzilla, Jira, Scarab,或任何你喜歡的問題管理系統)的名稱和URL,本例為 jira -->
<issueManagement>
<!-- 問題管理系統(例如jira)的名字, -->
<system> jira </system>
<!-- 該項目使用的問題管理系統的URL -->
<url> http://jira.baidu.com/banseon </url>
</issueManagement>
<!-- 項目持續集成信息 -->
<ciManagement>
<!-- 持續集成系統的名字,例如continuum -->
<system />
<!-- 該項目使用的持續集成系統的URL(如果持續集成系統有web接口的話)。 -->
<url />
<!-- 構建完成時,需要通知的開發者/用戶的配置項。包括被通知者信息和通知條件(錯誤,失敗,成功,警告) -->
<notifiers>
<!-- 配置一種方式,當構建中斷時,以該方式通知用戶/開發者 -->
<notifier>
<!-- 傳送通知的途徑 -->
<type />
<!-- 發生錯誤時是否通知 -->
<sendOnError />
<!-- 構建失敗時是否通知 -->
<sendOnFailure />
<!-- 構建成功時是否通知 -->
<sendOnSuccess />
<!-- 發生警告時是否通知 -->
<sendOnWarning />
<!-- 不贊成使用。通知發送到哪里 -->
<address />
<!-- 擴展配置項 -->
<configuration />
</notifier>
</notifiers>
</ciManagement>
<!-- 項目創建年份,4位數字。當產生版權信息時需要使用這個值。 -->
<inceptionYear />
<!-- 項目相關郵件列表信息 -->
<mailingLists>
<!-- 該元素描述了項目相關的所有郵件列表。自動產生的網站引用這些信息。 -->
<mailingList>
<!-- 郵件的名稱 -->
<name> Demo </name>
<!-- 發送郵件的地址或鏈接,如果是郵件地址,創建文檔時,mailto: 鏈接會被自動創建 -->
<post> banseon@126.com </post>
<!-- 訂閱郵件的地址或鏈接,如果是郵件地址,創建文檔時,mailto: 鏈接會被自動創建 -->
<subscribe> banseon@126.com </subscribe>
<!-- 取消訂閱郵件的地址或鏈接,如果是郵件地址,創建文檔時,mailto: 鏈接會被自動創建 -->
<unsubscribe> banseon@126.com </unsubscribe>
<!-- 你可以瀏覽郵件信息的URL -->
<archive> http:/hi.baidu.com/banseon/demo/dev/ </archive>
</mailingList>
</mailingLists>
<!-- 項目開發者列表 -->
<developers>
<!-- 某個項目開發者的信息 -->
<developer>
<!-- SCM里項目開發者的唯一標識符 -->
<id> HELLO WORLD </id>
<!-- 項目開發者的全名 -->
<name> banseon </name>
<!-- 項目開發者的email -->
<email> banseon@126.com </email>
<!-- 項目開發者的主頁的URL -->
<url />
<!-- 項目開發者在項目中扮演的角色,角色元素描述了各種角色 -->
<roles>
<role> Project Manager </role>
<role> Architect </role>
</roles>
<!-- 項目開發者所屬組織 -->
<organization> demo </organization>
<!-- 項目開發者所屬組織的URL -->
<organizationUrl> http://hi.baidu.com/banseon </organizationUrl>
<!-- 項目開發者屬性,如即時消息如何處理等 -->
<properties>
<dept> No </dept>
</properties>
<!-- 項目開發者所在時區, -11到12范圍內的整數。 -->
<timezone> -5 </timezone>
</developer>
</developers>
<!-- 項目的其他貢獻者列表 -->
<contributors>
<!-- 項目的其他貢獻者。參見developers/developer元素 -->
<contributor>
<name /><email /><url /><organization /><organizationUrl /><roles /><timezone /><properties />
</contributor>
</contributors>
<!-- 該元素描述了項目所有License列表。 應該只列出該項目的license列表,不要列出依賴項目的 license列表。如果列出多個license,用戶可以選擇它們中的一個而不是接受所有license。 -->
<licenses>
<!-- 描述了項目的license,用于生成項目的web站點的license頁面,其他一些報表和validation也會用到該元素。 -->
<license>
<!-- license用于法律上的名稱 -->
<name> Apache 2 </name>
<!-- 官方的license正文頁面的URL -->
<url> http://www.baidu.com/banseon/LICENSE-2.0.txt </url>
<!-- 項目分發的主要方式:
repo,可以從Maven庫下載
manual, 用戶必須手動下載和安裝依賴 -->
<distribution> repo </distribution>
<!-- 關于license的補充信息 -->
<comments> A business-friendly OSS license </comments>
</license>
</licenses>
<!-- SCM(Source Control Management)標簽允許你配置你的代碼庫,供Maven web站點和其它插件使用。 -->
<scm>
<!-- SCM的URL,該URL描述了版本庫和如何連接到版本庫。欲知詳情,請看SCMs提供的URL格式和列表。該連接只讀。 -->
<connection>
scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)
</connection>
<!-- 給開發者使用的,類似connection元素。即該連接不僅僅只讀 -->
<developerConnection>
scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk
</developerConnection>
<!-- 當前代碼的標簽,在開發階段默認為HEAD -->
<tag />
<!-- 指向項目的可瀏覽SCM庫(例如ViewVC或者Fisheye)的URL。 -->
<url> http://svn.baidu.com/banseon </url>
</scm>
<!-- 描述項目所屬組織的各種屬性。Maven產生的文檔用 -->
<organization>
<!-- 組織的全名 -->
<name> demo </name>
<!-- 組織主頁的URL -->
<url> http://www.baidu.com/banseon </url>
</organization>
<!-- 構建項目需要的信息 -->
<build>
<!-- 該元素設置了項目源碼目錄,當構建項目的時候,構建系統會編譯目錄里的源碼。該路徑是相對于pom.xml的相對路徑。 -->
<sourceDirectory />
<!-- 該元素設置了項目腳本源碼目錄,該目錄和源碼目錄不同:絕大多數情況下,該目錄下的內容 會被拷貝到輸出目錄(因為腳本是被解釋的,而不是被編譯的)。 -->
<scriptSourceDirectory />
<!-- 該元素設置了項目單元測試使用的源碼目錄,當測試項目的時候,構建系統會編譯目錄里的源碼。該路徑是相對于pom.xml的相對路徑。 -->
<testSourceDirectory />
<!-- 被編譯過的應用程序class文件存放的目錄。 -->
<outputDirectory />
<!-- 被編譯過的測試class文件存放的目錄。 -->
<testOutputDirectory />
<!-- 使用來自該項目的一系列構建擴展 -->
<extensions>
<!-- 描述使用到的構建擴展。 -->
<extension>
<!-- 構建擴展的groupId -->
<groupId />
<!-- 構建擴展的artifactId -->
<artifactId />
<!-- 構建擴展的版本 -->
<version />
</extension>
</extensions>
<!-- 當項目沒有規定目標(Maven2 叫做階段)時的默認值 -->
<defaultGoal />
<!-- 這個元素描述了項目相關的所有資源路徑列表,例如和項目相關的屬性文件,這些資源被包含在最終的打包文件里。 -->
<resources>
<!-- 這個元素描述了項目相關或測試相關的所有資源路徑 -->
<resource>
<!-- 描述了資源的目標路徑。該路徑相對target/classes目錄(例如${project.build.outputDirectory})。舉個例子,如果你想資源在特定的包里(org.apache.maven.messages),你就必須該元素設置為org/apache/maven/messages。然而,如果你只是想把資源放到源碼目錄結構里,就不需要該配置。 -->
<targetPath />
<!-- 是否使用參數值代替參數名。參數值取自properties元素或者文件里配置的屬性,文件在filters元素里列出。 -->
<filtering />
<!-- 描述存放資源的目錄,該路徑相對POM路徑 -->
<directory />
<!-- 包含的模式列表,例如**/*.xml. -->
<includes />
<!-- 排除的模式列表,例如**/*.xml -->
<excludes />
</resource>
</resources>
<!-- 這個元素描述了單元測試相關的所有資源路徑,例如和單元測試相關的屬性文件。 -->
<testResources>
<!-- 這個元素描述了測試相關的所有資源路徑,參見build/resources/resource元素的說明 -->
<testResource>
<targetPath /><filtering /><directory /><includes /><excludes />
</testResource>
</testResources>
<!-- 構建產生的所有文件存放的目錄 -->
<directory />
<!-- 產生的構件的文件名,默認值是${artifactId}-${version}。 -->
<finalName />
<!-- 當filtering開關打開時,使用到的過濾器屬性文件列表 -->
<filters />
<!-- 子項目可以引用的默認插件信息。該插件配置項直到被引用時才會被解析或綁定到生命周期。給定插件的任何本地配置都會覆蓋這里的配置 -->
<pluginManagement>
<!-- 使用的插件列表 。 -->
<plugins>
<!-- plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!-- 插件在倉庫里的group ID -->
<groupId />
<!-- 插件在倉庫里的artifact ID -->
<artifactId />
<!-- 被使用的插件的版本(或版本范圍) -->
<version />
<!-- 是否從該插件下載Maven擴展(例如打包和類型處理器),由于性能原因,只有在真需要下載時,該元素才被設置成enabled。 -->
<extensions />
<!-- 在構建生命周期中執行一組目標的配置。每個目標可能有不同的配置。 -->
<executions>
<!-- execution元素包含了插件執行需要的信息 -->
<execution>
<!-- 執行目標的標識符,用于標識構建過程中的目標,或者匹配繼承過程中需要合并的執行目標 -->
<id />
<!-- 綁定了目標的構建生命周期階段,如果省略,目標會被綁定到源數據里配置的默認階段 -->
<phase />
<!-- 配置的執行目標 -->
<goals />
<!-- 配置是否被傳播到子POM -->
<inherited />
<!-- 作為DOM對象的配置 -->
<configuration />
</execution>
</executions>
<!-- 項目引入插件所需要的額外依賴 -->
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<!-- 任何配置是否被傳播到子項目 -->
<inherited />
<!-- 作為DOM對象的配置 -->
<configuration />
</plugin>
</plugins>
</pluginManagement>
<!-- 使用的插件列表 -->
<plugins>
<!-- 參見build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId /><artifactId /><version /><extensions />
<executions>
<execution>
<id /><phase /><goals /><inherited /><configuration />
</execution>
</executions>
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals /><inherited /><configuration />
</plugin>
</plugins>
</build>
<!-- 在列的項目構建profile,如果被激活,會修改構建處理 -->
<profiles>
<!-- 根據環境參數或命令行參數激活某個構建處理 -->
<profile>
<!-- 構建配置的唯一標識符。即用于命令行激活,也用于在繼承時合并具有相同標識符的profile。 -->
<id />
<!-- 自動觸發profile的條件邏輯。Activation是profile的開啟鑰匙。profile的力量來自于它
能夠在某些特定的環境中自動使用某些特定的值;這些環境通過activation元素指定。activation元素并不是激活profile的唯一方式。 -->
<activation>
<!-- profile默認是否激活的標志 -->
<activeByDefault />
<!-- 當匹配的jdk被檢測到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4開頭的JDK。 -->
<jdk />
<!-- 當匹配的操作系統屬性被檢測到,profile被激活。os元素可以定義一些操作系統相關的屬性。 -->
<os>
<!-- 激活profile的操作系統的名字 -->
<name> windows XP </name>
<!-- 激活profile的操作系統所屬家族(如 'windows') -->
<family> Windows </family>
<!-- 激活profile的操作系統體系結構 -->
<arch> x86 </arch>
<!-- 激活profile的操作系統版本 -->
<version> 5.1.2600 </version>
</os>
<!-- 如果Maven檢測到某一個屬性(其值可以在POM中通過${名稱}引用),其擁有對應的名稱和值,Profile就會被激活。如果值
字段是空的,那么存在屬性名稱字段就會激活profile,否則按區分大小寫方式匹配屬性值字段 -->
<property>
<!-- 激活profile的屬性的名稱 -->
<name> mavenVersion </name>
<!-- 激活profile的屬性的值 -->
<value> 2.0.3 </value>
</property>
<!-- 提供一個文件名,通過檢測該文件的存在或不存在來激活profile。missing檢查文件是否存在,如果不存在則激活
profile。另一方面,exists則會檢查文件是否存在,如果存在則激活profile。 -->
<file>
<!-- 如果指定的文件存在,則激活profile。 -->
<exists> /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ </exists>
<!-- 如果指定的文件不存在,則激活profile。 -->
<missing> /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ </missing>
</file>
</activation>
<!-- 構建項目所需要的信息。參見build元素 -->
<build>
<defaultGoal />
<resources>
<resource>
<targetPath /><filtering /><directory /><includes /><excludes />
</resource>
</resources>
<testResources>
<testResource>
<targetPath /><filtering /><directory /><includes /><excludes />
</testResource>
</testResources>
<directory /><finalName /><filters />
<pluginManagement>
<plugins>
<!-- 參見build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId /><artifactId /><version /><extensions />
<executions>
<execution>
<id /><phase /><goals /><inherited /><configuration />
</execution>
</executions>
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals /><inherited /><configuration />
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- 參見build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId /><artifactId /><version /><extensions />
<executions>
<execution>
<id /><phase /><goals /><inherited /><configuration />
</execution>
</executions>
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals /><inherited /><configuration />
</plugin>
</plugins>
</build>
<!-- 模塊(有時稱作子項目) 被構建成項目的一部分。列出的每個模塊元素是指向該模塊的目錄的相對路徑 -->
<modules />
<!-- 發現依賴和擴展的遠程倉庫列表。 -->
<repositories>
<!-- 參見repositories/repository元素 -->
<repository>
<releases>
<enabled /><updatePolicy /><checksumPolicy />
</releases>
<snapshots>
<enabled /><updatePolicy /><checksumPolicy />
</snapshots>
<id /><name /><url /><layout />
</repository>
</repositories>
<!-- 發現插件的遠程倉庫列表,這些插件用于構建和報表 -->
<pluginRepositories>
<!-- 包含需要連接到遠程插件倉庫的信息.參見repositories/repository元素 -->
<pluginRepository>
<releases>
<enabled /><updatePolicy /><checksumPolicy />
</releases>
<snapshots>
<enabled /><updatePolicy /><checksumPolicy />
</snapshots>
<id /><name /><url /><layout />
</pluginRepository>
</pluginRepositories>
<!-- 該元素描述了項目相關的所有依賴。 這些依賴組成了項目構建過程中的一個個環節。它們自動從項目定義的倉庫中下載。要獲取更多信息,請看項目依賴機制。 -->
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<!-- 不贊成使用. 現在Maven忽略該元素. -->
<reports />
<!-- 該元素包括使用報表插件產生報表的規范。當用戶執行“mvn site”,這些報表就會運行。 在頁面導航欄能看到所有報表的鏈接。參見reporting元素 -->
<reporting>
</reporting>
<!-- 參見dependencyManagement元素 -->
<dependencyManagement>
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 參見distributionManagement元素 -->
<distributionManagement>
</distributionManagement>
<!-- 參見properties元素 -->
<properties />
</profile>
</profiles>
<!-- 模塊(有時稱作子項目) 被構建成項目的一部分。列出的每個模塊元素是指向該模塊的目錄的相對路徑 -->
<modules />
<!-- 發現依賴和擴展的遠程倉庫列表。 -->
<repositories>
<!-- 包含需要連接到遠程倉庫的信息 -->
<repository>
<!-- 如何處理遠程倉庫里發布版本的下載 -->
<releases>
<!-- true或者false表示該倉庫是否為下載某種類型構件(發布版,快照版)開啟。 -->
<enabled />
<!-- 該元素指定更新發生的頻率。Maven會比較本地POM和遠程POM的時間戳。這里的選項是:always(一直),daily(默認,每日),interval:X(這里X是以分鐘為單位的時間間隔),或者never(從不)。 -->
<updatePolicy />
<!-- 當Maven驗證構件校驗文件失敗時該怎么做:ignore(忽略),fail(失敗),或者warn(警告)。 -->
<checksumPolicy />
</releases>
<!-- 如何處理遠程倉庫里快照版本的下載。有了releases和snapshots這兩組配置,POM就可以在每個單獨的倉庫中,為每種類型的構件采取不同的策略。例如,可能有人會決定只為開發目的開啟對快照版本下載的支持。參見repositories/repository/releases元素 -->
<snapshots>
<enabled /><updatePolicy /><checksumPolicy />
</snapshots>
<!-- 遠程倉庫唯一標識符。可以用來匹配在settings.xml文件里配置的遠程倉庫 -->
<id> banseon-repository-proxy </id>
<!-- 遠程倉庫名稱 -->
<name> banseon-repository-proxy </name>
<!-- 遠程倉庫URL,按protocol://hostname/path形式 -->
<url> http://192.168.1.169:9999/repository/ </url>
<!-- 用于定位和排序構件的倉庫布局類型-可以是default(默認)或者legacy(遺留)。Maven 2為其倉庫提供了一個默認的布局;然而,Maven 1.x有一種不同的布局。我們可以使用該元素指定布局是default(默認)還是legacy(遺留)。 -->
<layout> default </layout>
</repository>
</repositories>
<!-- 發現插件的遠程倉庫列表,這些插件用于構建和報表 -->
<pluginRepositories>
<!-- 包含需要連接到遠程插件倉庫的信息.參見repositories/repository元素 -->
<pluginRepository>
</pluginRepository>
</pluginRepositories>
<!-- 該元素描述了項目相關的所有依賴。 這些依賴組成了項目構建過程中的一個個環節。它們自動從項目定義的倉庫中下載。要獲取更多信息,請看項目依賴機制。 -->
<dependencies>
<dependency>
<!-- 依賴的group ID -->
<groupId> org.apache.maven </groupId>
<!-- 依賴的artifact ID -->
<artifactId> maven-artifact </artifactId>
<!-- 依賴的版本號。 在Maven 2里, 也可以配置成版本號的范圍。 -->
<version> 3.8.1 </version>
<!-- 依賴類型,默認類型是jar。它通常表示依賴的文件的擴展名,但也有例外。一個類型可以被映射成另外一個擴展名或分類器。類型經常和使用的打包方式對應,盡管這也有例外。一些類型的例子:jar,war,ejb-client和test-jar。如果設置extensions為 true,就可以在plugin里定義新的類型。所以前面的類型的例子不完整。 -->
<type> jar </type>
<!-- 依賴的分類器。分類器可以區分屬于同一個POM,但不同構建方式的構件。分類器名被附加到文件名的版本號后面。例如,如果你想要構建兩個單獨的構件成JAR,一個使用Java 1.4編譯器,另一個使用Java 6編譯器,你就可以使用分類器來生成兩個單獨的JAR構件。 -->
<classifier></classifier>
<!-- 依賴范圍。在項目發布過程中,幫助決定哪些構件被包括進來。欲知詳情請參考依賴機制。
- compile :默認范圍,用于編譯
- provided:類似于編譯,但支持你期待jdk或者容器提供,類似于classpath
- runtime: 在執行時需要使用
- test: 用于test任務時使用
- system: 需要外在提供相應的元素。通過systemPath來取得
- systemPath: 僅用于范圍為system。提供相應的路徑
- optional: 當項目自身被依賴時,標注依賴是否傳遞。用于連續依賴時使用 -->
<scope> test </scope>
<!-- 僅供system范圍使用。注意,不鼓勵使用這個元素,并且在新的版本中該元素可能被覆蓋掉。該元素為依賴規定了文件系統上的路徑。需要絕對路徑而不是相對路徑。推薦使用屬性匹配絕對路徑,例如${java.home}。 -->
<systemPath></systemPath>
<!-- 當計算傳遞依賴時, 從依賴構件列表里,列出被排除的依賴構件集。即告訴maven你只依賴指定的項目,不依賴項目的依賴。此元素主要用于解決版本沖突問題 -->
<exclusions>
<exclusion>
<artifactId> spring-core </artifactId>
<groupId> org.springframework </groupId>
</exclusion>
</exclusions>
<!-- 可選依賴,如果你在項目B中把C依賴聲明為可選,你就需要在依賴于B的項目(例如項目A)中顯式的引用對C的依賴。可選依賴阻斷依賴的傳遞性。 -->
<optional> true </optional>
</dependency>
</dependencies>
<!-- 不贊成使用. 現在Maven忽略該元素. -->
<reports></reports>
<!-- 該元素描述使用報表插件產生報表的規范。當用戶執行“mvn site”,這些報表就會運行。 在頁面導航欄能看到所有報表的鏈接。 -->
<reporting>
<!-- true,則,網站不包括默認的報表。這包括“項目信息”菜單中的報表。 -->
<excludeDefaults />
<!-- 所有產生的報表存放到哪里。默認值是${project.build.directory}/site。 -->
<outputDirectory />
<!-- 使用的報表插件和他們的配置。 -->
<plugins>
<!-- plugin元素包含描述報表插件需要的信息 -->
<plugin>
<!-- 報表插件在倉庫里的group ID -->
<groupId />
<!-- 報表插件在倉庫里的artifact ID -->
<artifactId />
<!-- 被使用的報表插件的版本(或版本范圍) -->
<version />
<!-- 任何配置是否被傳播到子項目 -->
<inherited />
<!-- 報表插件的配置 -->
<configuration />
<!-- 一組報表的多重規范,每個規范可能有不同的配置。一個規范(報表集)對應一個執行目標 。例如,有1,2,3,4,5,6,7,8,9個報表。1,2,5構成A報表集,對應一個執行目標。2,5,8構成B報表集,對應另一個執行目標 -->
<reportSets>
<!-- 表示報表的一個集合,以及產生該集合的配置 -->
<reportSet>
<!-- 報表集合的唯一標識符,POM繼承時用到 -->
<id />
<!-- 產生報表集合時,被使用的報表的配置 -->
<configuration />
<!-- 配置是否被繼承到子POMs -->
<inherited />
<!-- 這個集合里使用到哪些報表 -->
<reports />
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
<!-- 繼承自該項目的所有子項目的默認依賴信息。這部分的依賴信息不會被立即解析,而是當子項目聲明一個依賴(必須描述group ID和artifact ID信息),如果group ID和artifact ID以外的一些信息沒有描述,則通過group ID和artifact ID匹配到這里的依賴,并使用這里的依賴信息。 -->
<dependencyManagement>
<dependencies>
<!-- 參見dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 項目分發信息,在執行mvn deploy后表示要發布的位置。有了這些信息就可以把網站部署到遠程服務器或者把構件部署到遠程倉庫。 -->
<distributionManagement>
<!-- 部署項目產生的構件到遠程倉庫需要的信息 -->
<repository>
<!-- 是分配給快照一個唯一的版本號(由時間戳和構建流水號)?還是每次都使用相同的版本號?參見repositories/repository元素 -->
<uniqueVersion />
<id> banseon-maven2 </id>
<name> banseon maven2 </name>
<url> file://${basedir}/target/deploy </url>
<layout />
</repository>
<!-- 構件的快照部署到哪里?如果沒有配置該元素,默認部署到repository元素配置的倉庫,參見distributionManagement/repository元素 -->
<snapshotRepository>
<uniqueVersion />
<id> banseon-maven2 </id>
<name> Banseon-maven2 Snapshot Repository </name>
<url> scp://svn.baidu.com/banseon:/usr/local/maven-snapshot </url>
<layout />
</snapshotRepository>
<!-- 部署項目的網站需要的信息 -->
<site>
<!-- 部署位置的唯一標識符,用來匹配站點和settings.xml文件里的配置 -->
<id> banseon-site </id>
<!-- 部署位置的名稱 -->
<name> business api website </name>
<!-- 部署位置的URL,按protocol://hostname/path形式 -->
<url>
scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web
</url>
</site>
<!-- 項目下載頁面的URL。如果沒有該元素,用戶應該參考主頁。使用該元素的原因是:幫助定位那些不在倉庫里的構件(由于license限制)。 -->
<downloadUrl />
<!-- 如果構件有了新的group ID和artifact ID(構件移到了新的位置),這里列出構件的重定位信息。 -->
<relocation>
<!-- 構件新的group ID -->
<groupId />
<!-- 構件新的artifact ID -->
<artifactId />
<!-- 構件新的版本號 -->
<version />
<!-- 顯示給用戶的,關于移動的額外信息,例如原因。 -->
<message />
</relocation>
<!-- 給出該構件在遠程倉庫的狀態。不得在本地項目中設置該元素,因為這是工具自動更新的。有效的值有:none(默認),converted(倉庫管理員從Maven 1 POM轉換過來),partner(直接從伙伴Maven 2倉庫同步過來),deployed(從Maven 2實例部署),verified(被核實時正確的和最終的)。 -->
<status />
</distributionManagement>
<!-- 以值替代名稱,Properties可以在整個POM中使用,也可以作為觸發條件(見settings.xml配置文件里activation元素的說明)。格式是<name>value</name>。 -->
<properties />
</project>