Maven 4 的新特性
1. 概述
Maven 為 Java 建構生態系統提供了近二十年的支援。 Maven 3 於 2010 年發布,此後社群一直期待著一次重大更新。如今,Maven 4 帶來了更佳的效能、更清晰的模型語意、更強的可擴展性和更現代化的依賴關係解析。
本文將探討 Maven 4 的主要變化,展示新特性並提供程式碼範例。更多詳情請參閱Maven 文件。
本文以 Maven 4 RC5 為參考版本。截至撰寫本文時,Apache Maven 專案尚未公佈 Maven 4 的正式版發布日期。因此,本文所有範例和說明均基於最新的候選版本。我們需要明確聲明預設插件(特別是maven-compiler-plugin 、 maven-install-plugin,和maven-deploy-plugin )的 4.x beta 版本,因為候選版本並未將其作為預設版本提供。
2. 模型版本 4.1.0
Maven 4 將 POM 版本更新至 4.1.0。它與 4.0.0 版本相容,但添加了一些元素並將一些元素標記為已棄用。
POM現在看起來像這樣:
<project
xmlns="http://maven.apache.org/POM/4.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
<modelVersion>4.1.0</modelVersion>
<!-- ... -->
</project>
我們可以省略modelVersion元素,因為 Maven 會從 schema 中取得它。
更新現有項目是可選的。 Maven 4 可以建置版本為 4.0.0 或 4.1.0 的項目,但新功能僅適用於更新後的版本。
3. 建構/消費者分離
在 Maven 3 中,庫的 POM 檔案包含了建置元數據,例如插件配置。這會導致依賴解析過程臃腫,並暴露內部細節。
Maven 4將建置 POM 與使用者 POM 分離。我們保留先前的建置 POM,Maven 會為依賴使用者產生使用者 POM。
消費者 POM 檔案不包含建置特定的資訊、父 POM 引用和未使用的依賴項。它僅包含專案使用的傳遞依賴項和託管依賴項。屬性會就地解析。
我們將這種轉換稱為「 flattening” 。 Maven 3 需要Flatten Maven 插件,但新版本的 Maven Install 和 Deploy 插件在使用下列命令列選項時可以原生處理此操作:
mvn \
clean install \
-Dmaven.consumer.pom.flatten=true
4. 新的神器類型
對於依賴項,我們可以指定一個 ` <type>來引用非預設打包方式的構件。 Maven 在《預設構件處理器參考》中定義了幾種類型。
對於普通的 JAR 文件,Maven 會將其新增至類別路徑。如果 JAR 檔案包含module-info.class ,Maven 會將其新增至模組路徑中(假設我們使用 Java 模組)。 Maven 4 增加了<type>classpath-jar</type>和<type>module-jar</type>來明確地控制這一行為。
我們也新增了三種類型來簡化註解處理器註冊: processor 、 classpath-processor和modular-processor 。我們只需新增依賴項,而無需配置諸如maven-compiler-plugin.
例如,使用 Lombok 和 Maven 4,我們可以寫:
<project>
<properties>
<lombok.version>1.18.42</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<type>classpath-processor</type>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
我們需要這兩個依賴項,因為 Maven 4 將 API 和處理器類別路徑分開了。
在未來的版本中,Maven 可能會擴展類型列表,例如,用於擴展taglet或doclet路徑。
5. 子項目
Java 9 引進 Java Modules 後, Maven Modules變得令人困惑。因此,Maven 4 將Modules重新命名為Subprojects 。現在,POM 檔案中有了subprojects元素,而modules元素則被標記為已棄用。
<subprojects>
<subproject>project-a</subproject>
<subproject>project-b</subproject>
</subprojects>
還有一些其他的改進:
- 父元素推論:我們可以使用不帶座標的空
parent元素。 Maven 會從聚合器 POM 檔案推斷出父元素。 - 子專案發現:我們可以省略
subprojects元素,Maven 會找到所有包含pom.xml子資料夾。 - 所有子項目打包歸檔文件中的時間戳記保持一致
- 安全部署:如果一個子專案失敗,其他子專案也不會部署到儲存庫。
6. 生命週期改進
Maven 4 引入了基於樹狀結構的生命週期。每個專案獨立經歷各個階段,依賴專案只有在依賴項達到就緒階段後才會啟動。這顯著提升了多項目建置的效能。我們透過以下方式啟用它:
mvn -b concurrent verify
**現在每個階段都包含before:和after: ` 鉤子。**這些鉤子取代了舊的pre-和post-階段,後者現在為了向後相容而用作別名。例如, maven-gpg-plugin:sign可以綁定到before:install而不是verify ,這在語義上是正確的。 `after after: ` 鉤子僅在主階段成功執行後運行。
Maven 4 還為all階段和each階段添加了鉤子。這些鉤子可以幫助我們針對每個專案樹或每個階段運行一次邏輯,從而使多專案建置更加可預測。
7. 進一步的變更
一些較小的改變會影響升級:
- 使用
-PmyProfile啟動不存在的設定檔會失敗。請使用-P?myProfile將設定檔設為可選,以避免失敗。 - 我們可以使用
–fail-on-severity或-fos來使建置在日誌層級失敗。
接下來,我們將探討一些其他能夠提升 Maven 4 彈性的變化。
7.1. 基於條件的設定檔激活
Maven 4 為設定檔啟動新增了condition元素。這允許我們使用函數聲明複雜的表達式:
<project>
<!-- ... -->
<profiles>
<profile>
<id>conditional-profile</id>
<activation>
<!-- use <condition><![CDATA[...]]></condition> to avoid encoding XML entities -->
<condition>exists('${project.basedir}/src/** /*.xsd') && length(${user.name}) > 5</condition>
</activation>
<!-- ... -->
</profile>
</profiles>
</project>
7.2. 來源目錄
在 Maven 3 中,我們使用兩個專門的元素來聲明自訂來源根目錄。這種方法雖然可行,但當我們想要管理多個目錄或進行更細粒度的過濾時,就會受到限制:
<project>
<!-- Maven 3 -->
<build>
<sourceDirectory>my-custom-dir/foo</sourceDirectory>
<testSourceDirectory>my-custom-dir/bar</testSourceDirectory>
</build>
</project>
Maven 4 引入了統一的sources配置部分。我們可以列出所需的任意數量的源根目錄,分配作用域,並準備更高級的配置,而無需額外的插件:
<project>
<!-- Maven 4 -->
<build>
<sources>
<source>
<scope>main</scope>
<directory>my-custom-dir/foo</directory>
</source>
<source>
<scope>test</scope>
<directory>my-custom-dir/bar</directory>
</source>
</sources>
</build>
</project>
這種新模型可以很好地擴展到多版本專案、基於模組的佈局,以及我們希望直接在 POM 中應用包含或排除規則的情況。
8. Maven 4 升級工具
Maven 4 增加了一個升級工具,用於將專案從 Maven 3 遷移過來。它會掃描 POM 檔案、插件和結構,然後推薦更新。
我們可以用以下命令運行它:
mvnup apply
如果我們只想取得工具建議的更改報告,而不修改pom.xml ,我們可以進行一次模擬運行:
mvnup check
9. 結論
在本教程中,我們了解到 Maven 4 透過更清晰的 POM 模型、分離的構建和用戶工件以及對模組和註解處理器的更好支持,實現了 Java 構建的現代化。更新後的生命週期改進了多專案和並發建置。鉤子函數使我們能夠進行精確控制,而較小的變更則提高了可複現性。
升級工具簡化了從 Maven 3 的遷移。總體而言,Maven 4 提高了效能、清晰度和可維護性,為現代 Java 專案奠定了堅實的基礎。
與往常一樣,本文中提供的程式碼可在 GitHub 上找到。