Maven介紹:
Maven是一個(gè)強大的Java項目構建工具。當然,你也可以使用其它工具來(lái)構建項目,但由于Maven是用Java開(kāi)發(fā)的,因此Maven被更多的用于Java項目中。
這篇教程的目的是幫助你理解Maven的工作機制。因此教程主要關(guān)注Maven的核心概念。一旦你理解了這些核心概念,當你想了解更多的細節時(shí),再取查看Maven文檔,或者從網(wǎng)上搜索,就變得容易多了。
事實(shí)上,Maven開(kāi)發(fā)者認為Maven不僅僅是一個(gè)構建工具。你可以去閱讀他們的文檔Maven哲學(xué),看看他們是怎么想的。但是現在,我們就把Maven當作一個(gè)構建工具,當你理解和開(kāi)始使用Maven后,你就明白Mavan到底是什么了。
本教程基于Maven 3.0.5。Maven網(wǎng)站的地址為:http://maven.apache.org,你可以從該網(wǎng)站上下載最新版的Maven,并關(guān)注項目的進(jìn)展。
什么是構建工具?
構建工具是將軟件項目構建相關(guān)的過(guò)程自動(dòng)化的工具。構建一個(gè)軟件項目通常包含以下一個(gè)或多個(gè)過(guò)程:
有些項目可能需要更多的過(guò)程才能完成構建,這些過(guò)程一般也可以整合到構建工具中,因此它們也可以實(shí)現自動(dòng)化。
自動(dòng)化構建過(guò)程的好處是將手動(dòng)構建過(guò)程中犯錯的風(fēng)險降到最低。而且,自動(dòng)構建工具通常要比手動(dòng)執行同樣的構建過(guò)程要快。
安裝Maven
安裝Maven,訪(fǎng)問(wèn)Maven下載頁(yè),然后按照安裝指南的步驟即可??偨Y一下,你需要做:
1. 下載并解壓Maven;
2. 將環(huán)境變量M2_HOME設置為解壓后的目錄;
3. 將M2環(huán)境變量設置為M2_HOME/bin(在Windows上是%M2_HOME%/bin,在Unix上是$M2_HOME/bin);
4. 將M2添加到PATH環(huán)境變量中(Windows上是%M2%,Unix上是$M2);
5. 打開(kāi)終端輸入`mvn`(不帶引號),然后回車(chē);
輸入‘mvn’命令后,終端上回顯示錯誤信息。不要擔心這個(gè)錯誤。因為你沒(méi)有給Maven傳入pom文件,因此出現該錯誤信息是意料之中的。顯示Maven錯誤信息說(shuō)明Maven已經(jīng)安裝好了。
注意:Maven運行需要Java環(huán)境,因此也需要安裝Java,Java版本1.5及以上;
Maven概覽-核心概念
Maven的中心思想是POM文件(項目對象模型)。POM文件是以XML文件的形式表述項目的資源,如源碼、測試代碼、依賴(lài)(用到的外部Jar包)等。POM文件應該位于項目的根目錄下。
下圖說(shuō)明了Maven是如何使用POM文件的,以及POM文件的主要組成部分:

這些概念先簡(jiǎn)單地解釋一下,更多的細節放在本教程的具體小節中。
POM文件
當你執行一條Maven命令的時(shí)候,你會(huì )傳入一個(gè)pom文件。Maven會(huì )在該pom文件描述的資源上執行該命令。
構建生命周期、階段和目標
Maven的構建過(guò)程被分解為構建生命周期、階段和目標。一個(gè)構建周期由一系列的構建階段組成,每一個(gè)構建階段由一系列的目標組成。當你運行Maven的時(shí)候,你會(huì )傳入一條命令。這條命令就是構建生命周期、階段或目標的名字。如果執行一個(gè)生命周期,該生命周期內的所有構建階段都會(huì )被執行。如果執行一個(gè)構建階段,在預定義的構建階段中,所有處于當前構建階段之前的階段也都會(huì )被執行。
依賴(lài)和倉庫
Maven執行時(shí),其中一個(gè)首要目標就是檢查項目的依賴(lài)。依賴(lài)是你的項目用到的jar文件(java庫)。如果在本地倉庫中不存在該依賴(lài),則Maven會(huì )從中央倉庫下載并放到本地倉庫。本地倉庫只是你電腦硬盤(pán)上的一個(gè)目錄。你可以根據需要制定本地倉庫的位置。你也可以指定下載依賴(lài)的遠程倉庫的地址。這些將會(huì )在后續的小節中詳細介紹。
插件
構建插件可以向構建階段中增加額外的構建目標。如果Maven標準的構建階段和目標無(wú)法滿(mǎn)足項目構建的需求,你可以在POM文件里增加插件。Maven有一些標準的插件供選用,如果需要你可以自己實(shí)現插件。
配置文件
配置文件用于以不同的方式構建項目。比如,你可能需要在本地環(huán)境構建,用于開(kāi)發(fā)和測試,你也可能需要構建后用于開(kāi)發(fā)環(huán)境。這兩個(gè)構建過(guò)程是不同的。在POM文件中增加不同的構建配置,可以啟用不同的構建過(guò)程。當運行Maven時(shí),可以指定要使用的配置。
Maven與Ant
Ant是Apache另一個(gè)流行的構建工具。如果你熟悉Ant,正在學(xué)習Maven,你將會(huì )注意到兩者在方法上的區別。
Ant使用命令式的方式,即你需要在A(yíng)nt構建文件里指定Ant應該執行的操作。你可以指定低級別的操作,如復制文件、編譯代碼等。你指定操作,還需要執行這些操作執行的順序。Ant沒(méi)有默認的目錄結構。
Maven使用聲明式的方式,即你需要在POM文件里指定做什么,而不是如何做。POM文件描述項目的資源-而不是如何構建。相比而言,Ant構建文件描述的是如何構建項目。在Maven里,如何構建是在“Maven 構建聲明周期、階段和目標”中預定義的。
Maven POM 文件
Maven的POM文件是一個(gè)xml文件,描述項目用到的資源,包括源代碼目錄、測試代碼目錄等的位置,以及項目依賴(lài)的外部jar包。
POM文件描述的是構建“什么”,而不是“如何”構建。如何構建是取決于Maven的構建階段和目標。當然,如果需要,你也可以向Maven構建階段中添加自定義的目標。
每一個(gè)項目都有一個(gè)POM文件。POM文件即pom.xml,應該放在項目的根目錄下。一個(gè)項目如果分為多個(gè)子項目,一般來(lái)講,父項目有一個(gè)POM文件,每一個(gè)子項目都有一個(gè)POM文件。在這種結構下,既可以一步構建整個(gè)項目,也可以各個(gè)子項目分開(kāi)構建。
本文剩下的章節,主要介紹POM文件最重要的部分。POM文件的完整文檔,參考[Maven POM Reference](http://maven.apache.org/pom.html)
如下為一個(gè)最小化的POM文件示例:
<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/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion><groupId>com.jenkov</groupId>
<artifactId>java-web-crawler</artifactId>
<version>1.0.0</version>
</project>
*modelVersion*屬性表示使用的POM模型的版本。選擇和你正在使用的Maven版本一致的版本即可。版本4.0.0適用于Maven 2和3。
*groupId”屬性是一個(gè)組織或者項目(比如開(kāi)源項目)的唯一ID。大多數情況下,你會(huì )使用項目的java包的根名稱(chēng)作為group ID。例如,對于我自己的Java網(wǎng)絡(luò )爬蟲(chóng)項目,我會(huì )使用com.jenkov作為group ID。如果這個(gè)項目是一個(gè)由很多獨立的貢獻者組成的開(kāi)源項目,也許選擇與項目相關(guān)的名稱(chēng)作為group ID,比選擇與我的公司相關(guān)的名稱(chēng)名作為group ID要合理地多。因此,選擇com.javawebcrawler作為group ID。
groupId不一定非要使用Java的包名,也不一定要使用.分隔符來(lái)分隔ID中的詞。但是,如果你這么使用,項目將會(huì )位于Maven倉庫的結構化目錄中,該結構化目錄與group ID匹配。每一個(gè).是一個(gè)目錄分隔符,每一個(gè)詞都表示一個(gè)目錄。group ID為com.jenkov的項目將位于目錄MAVEN_REPO/com/jenkov中。目錄路徑中的MAVEN_REPO表示Maven倉庫的路徑。
*artifactId*屬性包含你正在構建的項目的名稱(chēng)。以我的Java網(wǎng)絡(luò )爬蟲(chóng)項目來(lái)說(shuō),artifact ID為java-web-crawler。artifact ID是Maven倉庫中g(shù)roup ID目錄下的子目錄名。artifact ID也是構建完項目后生成的jar包的文件名的一部分。構建過(guò)程的輸出,即構建結果,在Maven中成為構件(artifact)。通常它就是一個(gè)jar包、war包或者EAR包,蛋它也可以是別的。
*versionId包含項目的版本號。如果你的項目有不同的發(fā)行版,比如開(kāi)源API,對構建過(guò)程版本化是很有用的。如果使用版本,項目的用戶(hù)就可以查看項目的具體版本。版本號是artifact ID目錄下的子目錄名。版本號也用作構建結果名稱(chēng)的一部分。(即jar包文件名的一部分–譯者注)
上文中的groupId,artifactId和version屬性,在項目構建后會(huì )生成一個(gè)jar文件,位于Maven倉庫的如下路徑中(目錄和文件名):MAVEN_REPO/com/jenkov/java-web-crawler/1.0.0/java-web-crawler-1.0.0.jar
如果你的項目使用[Maven目錄結構](http://tutorials.jenkov.com/maven/maven-tutorial.html#maven-directory-structure),而且項目沒(méi)有外部依賴(lài),上面的最簡(jiǎn)化POM文件就是你構建項目所需的所有配置了。
如果你的項目不遵從標準的目錄結構,有外部依賴(lài)或者在構建過(guò)程中需要加入額外操作,你需要向POM文件中添加更多的配置。更多的配置查閱[Maven POM 參考](鏈接在上文)。
通常,你可以向POM文件中增加各種配置,這些配置告訴Maven如何更好地構建你的項目。查閱Maven的POM參考,了解更多的配置。
父pom
所有的Maven pom文件都繼承自一個(gè)父pom。如果沒(méi)有指定父pom,則該pom文件繼承自根pom。pom文件的繼承關(guān)系如下圖所示:

可以讓一個(gè)pom文件顯式地繼承另一個(gè)pom文件。這樣,可以通過(guò)修改公共父pom文件的設置來(lái)修改所有子pom文件的設置。在pom文件的起始處指定父pom,例如:
<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/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion><parent>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<relativePath>../my-parent</relativePath>
</parent><artifactId>my-project</artifactId>
…
</project>
子pom文件的設置可以覆蓋父pom文件的設置,只需要在子pom文件里指定新的設置即可。
關(guān)于pom文件繼承更詳細的內容可以參考Maven POM文檔。
有效pom
考慮到pom文件的繼承關(guān)系,當Maven執行的時(shí)候可能很難確定最終的pom文件的內容??偟膒om文件(所有繼承關(guān)系生效后)被稱(chēng)為有效pom(effective pom)??梢允褂靡韵碌拿钭孧aven打印出當前的有效pom:
mvn help:effective-pom
執行以上命令,Maven會(huì )將有效pom輸出到命令行。
Maven配置文件
Maven有兩個(gè)配置文件。配置文件里的設置,對所有的pom文件都是有效的。比如,你可以配置:
配置文件名為settings.xml,兩個(gè)配置文件分別為:
+ Maven安裝目錄中:$M2_HOME/conf/settings.xml
+ 用戶(hù)主目錄中:${user.home}/.m2/settings.xml
兩個(gè)配置文件都是可選的。如果兩個(gè)文件都存在,則用戶(hù)目錄下的配置會(huì )覆蓋Maven安裝目錄中的配置。
關(guān)于Maven配置文件,參考[Maven配置文檔](http://maven.apache.org/settings.html)
讓Maven跑起來(lái)
當你安裝好了Maven,并且在項目的根目錄下創(chuàng )建了POM文件,可以在項目上運行Maven了。
運行Maven只需在命令行執行`mvn`命令即可。當執行`mvn`命令時(shí),將構建周期、階段或目標作為參數傳進(jìn)去,Maven就會(huì )執行它們。例如:
mvn install
該命令執行`install`階段(是默認構建階段的一部分),編譯項目,將打包的JAR文件復制到本地的Maven倉庫。事實(shí)上,該命令在執行install之前,會(huì )執行在構建周期序列中位于install之前的所有階段。
你可以向mvn命令傳入多個(gè)參數,執行多個(gè)構建周期或階段,如:
mvn clean install
該命令首先執行clean構建周期,刪除Maven輸出目錄中已編譯的類(lèi)文件,然后執行install構建階段。
也可以執行一個(gè)Maven目標(構建階段的一部分),將構建階段與目標名以冒號(:)相連,作為參數一起傳給Maven命令。例如:
mvn dependency:copy-dependencies
該命令執行`dependency`構建階段中的`copy-dependencies`目標。
聯(lián)系客服