認識 Maven
介紹
Apache Maven,是一個軟體(特別是 Java 軟體)專案管理及自動構建工具,由 Apache 軟體基金會所提供。基於專案物件模型(Project Object Model, POM)概念,Maven 利用一個中央資訊片斷能管理一個專案的構建、報告和文件等步驟。
Maven 專案透過 POM 來建置專案,一但你熟悉一個 Maven 專案如何建置,你將會了解所有 Maven 專案如何建置。
安裝
Maven 是一個 Java 工具,執行前必須先安裝 Java。
- 下載 Maven 後解壓縮到目錄
- 預設函式庫位於: %username%\.m2,若要變更目錄於 maven_home/conf/settings.xml 進行變更
- 新增環境變數 M2_HOME 指定到 maven_home 目錄
- 將 maven_home\bin 加到 PATH
安裝 Maven 後執行:
mvn --version
驗證 mvn 指令是否正確回應,若有則安裝完成。
Goal
mvn 後接的指令稱為 goal,由 "前置字:識別字" 表示要執行的作業。如:
mvn clean package javadoc:javadoc exec:exec
上面指令的作用是先刪除 target 目錄後再行打包 Project,然後產生文件,再執行專案。其中 clean、package、javadoc:javadoc... 等都是 goal。
Lifecycle
Maven 有三個 Lifecycle,分別是 clean、site、default。
clean
clean 週期負責 Project 清理。
site
site 週期則是負責產生 Project 的文檔。
default
default 週期負責 Project 的建置,由多個 phase 組成,phase 內可以設定執行的 goals。當指定執行的 goal 為 default lifecycle 的 phase 時,maven 將會依序執行 default 內的 phase 至指定之 phase。舉例來說 mvn package,此時將會依序執行 validate、compile、test、package。
Phase (有序):
- validate: 驗證專案正確性以及所有必要資訊已備妥。
- compile: 編譯專案原始碼。
- test: 進行單元測試。
- package: 將相關檔案進行封裝,例如產生JAR 檔案。
- integration-test: 進行整合測試。
- verify: 驗證檔案封裝是否正確。
- install: 將封裝的檔案安裝至本地貯藏室(Local repository)。
- deploy: 部署檔案。
專案進行中很常使用的指令,舉例 mvn clean package 重新產生 target,或者如果專案內有使用 QueryDSL 也會很常需要呼叫 mvn clean compile 重新產生 Q-types Model 等。
POM
POM 是 Project Object Model(專案模型)的縮寫,為 Maven 專案的必要文件,其內容包含專案的描述,依賴,使用的 plugin,及 Maven 該如何建置專案的等配置說明。
Minimal POM
- POM 至少要求以下元素:
- project - root
- modelVersion - 必須設定為 4.0.0
- groupId - 專案的組織或公司
- artifactId - 專案的名稱
- version - 專案的版本號
範例:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
Project Inheritance
專案繼承時 child 將會繼承 parent 的元素,如 dependencies、developers、contributors、plugins 和 resources 等。下面用例子來講解 maven 的專案繼承。
Example 1
沿用上敘範例的 com.mycompany.app:my-app:1,宣告一個新的 artifact com.mycompany.app:my-module:1
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
此時的資料夾結構如下(有上下關係):
.
|-- my-module
| `-- pom.xml
`-- pom.xml
若我們希望 my-app 是 my-module 的 parent,此時 com.mycompany.app:my-module:1 的 POM 應該這樣設定:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
如果 my-module 的 groupId 與 version 希望可以跟 parent 一樣,此時我們可以移除 my-module 的設定:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<artifactId>my-module</artifactId>
</project>
Example 2
如果資料夾結構並不如上敘有 parent 與 child 之間有上下關係,而是平行呢? 結構如下:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
此時 parent section 可以加上 <relativePath> element 便可指定相對路徑以達到繼承效果:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>my-module</artifactId>
</project>
Project Aggregation
專案聚合功能與繼承功能類似,但不同於繼承是於每個模組設定 parent,聚合是在 parent 設定有哪些 modules。
Example 3
com.mycompany.app:my-app:1's POM
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
com.mycompany.app:my-module:1's POM
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
上下關係的資料夾結構:
.
|-- my-module
| `-- pom.xml
`-- pom.xml
此時我們希望以聚合的方式使 my-app 成為 my-module 的 parent,修改 my-app 的 POM:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>my-module</module>
</modules>
</project>
Example 4
平行的資料夾結構:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
修改 my-app 的 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>../my-module</module>
</modules>
</project>
至此專案的繼承介紹告一段落,專案內可以同時使用繼承與聚合,但案例較為複雜這邊就不做深入討論。
此篇介紹了 Maven 的基本概念與安裝使用方式,還有一些核心概念在此邊未提及,如 Profile、Dependence、Plugin 等設定都是專案進行中常使用的設定,希望閱讀完此篇後大家對 Maven 有個初步的認識。
REF: