Maven入門指南(一)

YatHo發表於2017-08-09

Maven介紹:

Maven是一個強大的Java專案構建工具。

 

什麼是構建工具?

構建工具是將軟體專案構建相關的過程自動化的工具。構建一個軟體專案通常包含以下一個或多個過程:

  • 生成原始碼(如果專案使用自動生成原始碼);
  • 從原始碼生成專案文件;
  • 編譯原始碼;
  • 將編譯後的程式碼打包成JAR檔案或者ZIP檔案;
  • 將打包好的程式碼安裝到伺服器、倉庫或者其它的地方;

有些專案可能需要更多的過程才能完成構建,這些過程一般也可以整合到構建工具中,因此它們也可以實現自動化。

自動化構建過程的好處是將手動構建過程中犯錯的風險降到最低。而且,自動構建工具通常要比手動執行同樣的構建過程要快。

 

安裝Maven

安裝Maven,訪問Maven下載頁,然後按照安裝指南的步驟即可。總結一下,你需要做:
1. 下載並解壓Maven;
2. 將環境變數M2_HOME設定為解壓後的目錄;
3. 將M2環境變數設定為M2_HOME/bin(在Windows上是%M2_HOME%/bin,在Unix上是${M2_HOME}/bin);
4. 將M2新增到PATH環境變數中(Windows上是%M2%,Unix上是${M2});
5. 開啟終端輸入`mvn`(不帶引號),然後回車;

輸入‘mvn’命令後,終端上回顯示錯誤資訊。不要擔心這個錯誤。因為你沒有給Maven傳入pom檔案,因此出現該錯誤資訊是意料之中的。顯示Maven錯誤資訊說明Maven已經安裝好了。

注意:Maven執行需要Java環境,因此也需要安裝Java,Java版本1.5及以上;

maven的JDK版本依賴

 

專案

要求

JDK

Maven 3.3 要求 JDK 1.7 或以上
Maven 3.2 要求 JDK 1.6 或以上
Maven 3.1 要求 JDK 1.5 或以上

 

Maven概覽-核心概念

Maven的中心思想是POM檔案(專案物件模型)。POM檔案是以XML檔案的形式表述專案的資源,如原始碼、測試程式碼、依賴(用到的外部Jar包)等。POM檔案應該位於專案的根目錄下。

下圖說明了Maven是如何使用POM檔案的,以及POM檔案的主要組成部分:

maven-overview-1

這些概念先簡單地解釋一下,更多的細節放在本教程的具體小節中。

 

POM檔案

當你執行一條Maven命令的時候,你會傳入一個pom檔案。Maven會在該pom檔案描述的資源上執行該命令。

 

構建生命週期、階段和目標

Maven的構建過程被分解為構建生命週期、階段和目標。一個構建週期由一系列的構建階段組成,每一個構建階段由一系列的目標組成。當你執行Maven的時候,你會傳入一條命令。這條命令就是構建生命週期、階段或目標的名字。如果執行一個生命週期,該生命週期內的所有構建階段都會被執行。如果執行一個構建階段,在預定義的構建階段中,所有處於當前構建階段之前的階段也都會被執行。

 

依賴和倉庫

Maven執行時,其中一個首要目標就是檢查專案的依賴。依賴是你的專案用到的jar檔案(java庫)。如果在本地倉庫中不存在該依賴,則Maven會從中央倉庫或遠端倉庫下載並放到本地倉庫。本地倉庫只是你電腦硬碟上的一個目錄。你可以根據需要制定本地倉庫的位置。你也可以指定下載依賴的遠端倉庫的地址。這些將會在後續的小節中詳細介紹。

 

外掛

構建外掛可以向構建階段中增加額外的構建目標。如果Maven標準的構建階段和目標無法滿足專案構建的需求,你可以在POM檔案裡增加外掛。Maven有一些標準的外掛供選用,如果需要你可以自己實現外掛。

 

配置檔案

配置檔案用於以不同的方式構建專案。比如,你可能需要在本地環境構建,用於開發和測試,你也可能需要構建後用於開發環境。這兩個構建過程是不同的。在POM檔案中增加不同的構建配置,可以啟用不同的構建過程。當執行Maven時,可以指定要使用的配置。

 

Maven與Ant

Ant是Apache另一個流行的構建工具。如果你熟悉Ant,正在學習Maven,你將會注意到兩者在方法上的區別。

Ant使用命令式的方式,即你需要在Ant構建檔案裡指定Ant應該執行的操作。你可以指定低階別的操作,如複製檔案、編譯程式碼等。你指定操作,還需要執行這些操作執行的順序。Ant沒有預設的目錄結構。

Maven使用宣告式的方式,即你需要在POM檔案裡指定做什麼,而不是如何做。POM檔案描述專案的資源-而不是如何構建。相比而言,Ant構建檔案描述的是如何構建專案。在Maven裡,如何構建是在“Maven 構建宣告週期、階段和目標”中預定義的。

 

Maven POM 檔案

Maven的POM檔案是一個xml檔案,描述專案用到的資源,包括原始碼目錄、測試程式碼目錄等的位置,以及專案依賴的外部jar包。

POM檔案描述的是構建“什麼”,而不是“如何”構建。如何構建是取決於Maven的構建階段和目標。當然,如果需要,你也可以向Maven構建階段中新增自定義的目標。

每一個專案都有一個POM檔案。POM檔案即pom.xml,應該放在專案的根目錄下。一個專案如果分為多個子專案,一般來講,父專案有一個POM檔案,每一個子專案都有一個POM檔案。在這種結構下,既可以一步構建整個專案,也可以各個子專案分開構建。

本文剩下的章節,主要介紹POM檔案最重要的部分。POM檔案的完整文件,參考[Maven POM Reference](http://maven.apache.org/pom.html)

如下為一個最小化的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”屬性是一個組織或者專案(比如開源專案)的唯一ID。大多數情況下,你會使用專案的java包的根名稱作為group ID。例如,對於我自己的Java網路爬蟲專案,我會使用com.jenkov作為group ID。如果這個專案是一個由很多獨立的貢獻者組成的開源專案,也許選擇與專案相關的名稱作為group ID,比選擇與我的公司相關的名稱名作為group ID要合理地多。因此,選擇com.javawebcrawler作為group ID。

groupId不一定非要使用Java的包名,也不一定要使用.分隔符來分隔ID中的詞。但是,如果你這麼使用,專案將會位於Maven倉庫的結構化目錄中,該結構化目錄與group ID匹配。每一個.是一個目錄分隔符,每一個詞都表示一個目錄。group ID為com.jenkov的專案將位於目錄MAVEN_REPO/com/jenkov中。目錄路徑中的MAVEN_REPO表示Maven倉庫的路徑。

*artifactId*屬性包含你正在構建的專案的名稱。以我的Java網路爬蟲專案來說,artifact ID為java-web-crawler。artifact ID是Maven倉庫中group ID目錄下的子目錄名。artifact ID也是構建完專案後生成的jar包的檔名的一部分。構建過程的輸出,即構建結果,在Maven中成為構件(artifact)。通常它就是一個jar包、war包或者EAR包,蛋它也可以是別的。

*versionId包含專案的版本號。如果你的專案有不同的發行版,比如開源API,對構建過程版本化是很有用的。如果使用版本,專案的使用者就可以檢視專案的具體版本。版本號是artifact ID目錄下的子目錄名。版本號也用作構建結果名稱的一部分。

 

上文中的groupId,artifactId和version屬性,在專案構建後會生成一個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),而且專案沒有外部依賴,上面的最簡化POM檔案就是你構建專案所需的所有配置了。

如果你的專案不遵從標準的目錄結構,有外部依賴或者在構建過程中需要加入額外操作,你需要向POM檔案中新增更多的配置。更多的配置查閱[Maven POM 參考]

通常,你可以向POM檔案中增加各種配置,這些配置告訴Maven如何更好地構建你的專案。查閱Maven的POM參考,瞭解更多的配置。

 

父pom

所有的Maven pom檔案都繼承自一個父pom。如果沒有指定父pom,則該pom檔案繼承自根pom。pom檔案的繼承關係如下圖所示:

super-pom

可以讓一個pom檔案顯式地繼承另一個pom檔案。這樣,可以通過修改公共父pom檔案的設定來修改所有子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檔案裡指定新的設定即可。
  關於pom檔案繼承更詳細的內容可以參考Maven POM文件。

有效pom

  考慮到pom檔案的繼承關係,當Maven執行的時候可能很難確定最終的pom檔案的內容。總的pom檔案(所有繼承關係生效後)被稱為有效pom(effective pom)。可以使用以下的命令讓Maven列印出當前的有效pom:

  mvn help:effective-pom 

執行以上命令,Maven會將有效pom輸出到命令列。

 

Maven配置檔案

  Maven有兩個配置檔案。配置檔案裡的設定,對所有的pom檔案都是有效的。比如,你可以配置:

    •   本地倉庫的路徑;
    •   當前的編譯配置選項
    •   等等

  配置檔名為settings.xml,兩個配置檔案分別為:

  + Maven安裝目錄中:$M2_HOME/conf/settings.xml
  + 使用者主目錄中:${user.home}/.m2/settings.xml

  兩個配置檔案都是可選的。如果兩個檔案都存在,則使用者目錄下的配置會覆蓋Maven安裝目錄中的配置。

  關於Maven配置檔案,參考[Maven配置文件](http://maven.apache.org/settings.html)

讓Maven跑起來

  當你安裝好了Maven,並且在專案的根目錄下建立了POM檔案,可以在專案上執行Maven了。

  執行Maven只需在命令列執行`mvn`命令即可。當執行`mvn`命令時,將構建週期、階段或目標作為引數傳進去,Maven就會執行它們。例如:

  mvn install

  該命令執行`install`階段(是預設構建階段的一部分),編譯專案,將打包的JAR檔案複製到本地的Maven倉庫。事實上,該命令在執行install之前,會執行在構建週期序列中位於install之前的所有階段。

  你可以向mvn命令傳入多個引數,執行多個構建週期或階段,如:

  mvn clean install

  該命令首先執行clean構建週期,刪除Maven輸出目錄中已編譯的類檔案,然後執行install構建階段。

  也可以執行一個Maven目標(構建階段的一部分),將構建階段與目標名以冒號(:)相連,作為引數一起傳給Maven命令。例如:

  mvn dependency:copy-dependencies

  該命令執行`dependency`構建階段中的`copy-dependencies`目標。