这篇文章详细介绍了 Maven 4(截至2025年10月尚未正式发布)的预期重大更新。它是一篇前瞻性的技术综述,旨在解释 Maven 团队如何通过这一版本让这个已有20多年历史的构建工具"重生",以适应现代开发需求,同时尽量不破坏现有的庞大生态系统。
下面我将从几个核心维度帮你系统地理解这篇文章的内容,并用中文清晰梳理其重点和意义:
🌟 一、Maven 4 的总体目标
Maven 自诞生以来一直保持高度向后兼容性,尤其是 POM 文件格式长期停留在 4.0.0 模型版本,导致难以进行结构性创新。
Maven 4 的核心目标是:在不破坏生态的前提下实现进化。
为此,Maven 团队提出一个关键理念:
🔑 把"构建所需的信息"与"消费者所需的信息"分离。
- 构建 POM(Build POM):用于实际编译、测试、打包项目,可以使用新语法、新特性。
- 消费 POM(Consumer POM) :部署到远程仓库(如 Maven Central),供其他项目依赖时读取,仍然保持
4.0.0格式,确保旧工具、IDE、CI 系统仍能正常工作。
这样既能让 Maven 自身发展,又不会强迫整个 Java 生态升级。
🛠️ 二、POM 结构的重大变革
✅ 1. 新的模型版本:4.1.0
- 命名空间变为:
http://maven.apache.org/POM/4.1.0 - 引入新元素,标记旧元素为弃用。
- 注意 :你不需要立即升级你的 POM 到
4.1.0,Maven 4 依然支持4.0.0。只有当你想用新功能时才需要升级。
✅ 2. "模块"改名为"子项目"(Subprojects)
- 老概念中的
<modules>被重命名为<subprojects>(原<modules>已标记为 deprecated)。 - 更清晰地区分 Java 9+ 的"模块系统"(JPMS)与 Maven 的"多模块项目"。
- 推荐说法:"多项目结构" vs "单项目结构"。
✅ 3. 自动生成 Consumer POM
- 构建完成后,Maven 会自动生成一个精简版的
pom.xml部署到仓库。 - 这个 consumer POM 是"扁平化"的:
- 移除
<parent>引用(继承内容已展开) - BOM 导入被展平进依赖列表
- 只保留必要的传递依赖(compile/runtime scope)
- 管理的依赖只保留真正使用的
- 移除
- 目的:让使用者无需下载父 POM 或理解复杂的内部结构即可正确解析依赖。
💾 三、新特性详解
📦 1. 新增 Artifact 类型(支持 JPMS)
为了更好地支持 Java 模块化(JPMS),Maven 4 引入了更精确的依赖类型:
| 类型 | 含义 |
|---|---|
jar |
默认,自动判断放 classpath 还是 module path |
classpath-jar |
强制放在 classpath |
modular-jar |
强制放在 module path |
processor, classpath-processor, modular-processor |
注解处理器专用 |
⚠️ 当前(2025年10月)仅
maven-compiler-plugin 4.0.0-beta-3+支持这些类型。
🧾 2. 新增 packaging 类型:bom
- 以前 Bill of Materials(BOM)通常用
pom打包类型表示。 - Maven 4 新增专门的
bom打包类型,语义更明确。 - 支持通过
<exclusions>排除 BOM 中的依赖。 - 支持带 classifier 的 BOM 导入(例如
myproject-bom-1.0.pom)。 - 警告:如果导入的是当前 reactor 内部的 BOM(即还没构建完成的),Maven 4 会发出警告,未来可能直接报错 ------ 推荐只导入外部发布的 BOM。
🗂️ 3. 更灵活的源码目录配置
老方式只能定义两个目录:
xml
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
Maven 4 支持多源码目录:
xml
<sources>
<source>
<scope>main</scope>
<directory>src/main/java</directory>
</source>
<source>
<scope>main</scope>
<directory>src/main/generated</directory>
</source>
<source>
<scope>test</scope>
<directory>src/test/java</directory>
</source>
</sources>
- 支持多个主/测试源码路径
- 统一管理 include/exclude 规则
- 更好支持 multi-release JAR 和模块化源码结构
🏗️ 4. 子项目改进:减少重复配置
(1) 自动版本推断(POM Inference)
- 不再需要在每个子项目中显式写
<version>。 - Maven 会自动从父项目或上下文推断版本号。
- 大大减少版本同步的工作量。
(2) 父项目自动推断(Parent Inference)
xml
<parent>
<relativePath>..</relativePath>
</parent>
<!-- 或简写 -->
<parent/>
- Maven 会自动查找上级目录的
pom.xml并填充groupId,artifactId,version。 - 减少冗余信息。
(3) 子项目自动发现
当满足以下条件时,Maven 4 会自动扫描并添加所有含 pom.xml 的子目录为 subproject:
- 父项目是
pom打包类型 - 没有显式声明
<subprojects>或<modules> - 子目录存在
pom.xml
类似 Gradle 的 convention over configuration。
🔁 5. CI/CD 友好变量全面支持
Maven 3 需要 flatten-maven-plugin 才能使用 ${revision} 等变量。
Maven 4 原生支持:
xml
<version>${revision}</version>
变量可通过以下方式传入:
- 命令行:
mvn install -Drevision=1.0.0 .mvn/maven.config文件- 父 POM 定义
支持任意命名的占位符,极大提升 CI 流水线灵活性。
🔄 四、构建生命周期与执行机制革新
🌲 1. 生命周期从"图"变"树"
- Maven 3:生命周期是一个线性阶段序列(validate → compile → test → package...)
- Maven 4:生命周期是树状结构,支持更细粒度的依赖控制。
- 配合
-b concurrent并发构建器,可实现真正的并行构建。 - 示例:A 项目只需
ready阶段完成,B 项目就能开始构建,而不必等到verify。
⏳ 2. 新增前后置阶段(before:/after:)
每个阶段都有对应的前置和后置阶段:
before:compile,after:compilebefore:test,after:test
还支持排序:
bash
before:integration-test[100]
before:integration-test[200]
⚠️ 老的
pre-*/post-*阶段已被弃用,应使用新的before:/after:。
🔄 行为变化:post-clean 现在会运行
xml
<phase>post-clean</phase>
- Maven 3:运行
mvn clean时,post-clean不执行。 - Maven 4:
mvn clean会自动执行before:clean和after:clean(即post-clean)。
这是一个行为变更,可能影响现有构建脚本!
🧩 3. 新增通用生命周期阶段:all 和 each
| 阶段 | 作用范围 | 用途 |
|---|---|---|
each |
每个子项目内部 | 在每个子项目的生命周期周围执行操作 |
all |
整个项目(含所有子项目) | 在整个构建周期周围执行操作 |
before:all |
整个构建开始前 | 初始化全局资源 |
after:all |
整个构建结束后 | 清理、报告汇总 |
before:each |
每个子项目开始前 | 子项目级初始化 |
after:each |
每个子项目结束后 | 子项目级清理 |
非常适合复杂项目的 setup/teardown 逻辑。
🔐 五、安全与性能增强
🔐 1. 全新加密系统(mvnenc)
- Maven 3 的加密实为"混淆",安全性差。
- Maven 4 使用独立 CLI 工具
mvnenc提供真正的加密/解密。 - 支持外部密钥管理(vaults)。
- 文档地址:https://maven.apache.org/guides/mini/guide-encryption.html
🚀 2. Maven Shell (mvnsh)
- 类似
mvnd(Maven Daemon),但更轻量。 - 启动一个持久化的 Maven shell,避免每次命令都重新加载 JVM 和配置。
- 显著提升频繁执行命令的效率。
🔍 3. Maven Resolver 2.0
- 重构的依赖解析库,超过 150 项改进。
- 使用 Java 17 原生 HTTP 客户端。
- 插件不再直接调用 Resolver,而是通过新 API 层。
🛠️ 六、插件与迁移支持
🧰 1. 插件 API 升级
- 插件模型变为不可变(immutable)。
- 强制使用 JSR-330 注解(如
@Inject)替代旧的 Plexus DI。 - 插件开发者需测试兼容性,建议先在 Maven 3.9.x 上验证。
🔀 2. Maven Upgrade Tool
帮助从 Maven 3 迁移到 4:
- 自动升级 POM 到
4.1.0 - 检测弃用特性并提示替换方案
- 验证项目是否 ready for Maven 4
📌 总结:Maven 4 到底带来了什么?
| 方面 | 改进点 | 对开发者的意义 |
|---|---|---|
| 架构设计 | 分离 Build POM 与 Consumer POM | 可自由演进,不破坏生态 |
| Java 版本 | 要求 JDK 17 | 利用现代语言特性,提升性能 |
| POM 管理 | 自动推断版本、父项目、子项目 | 减少重复配置,提升可维护性 |
| 模块化支持 | 新 artifact types(modular-jar 等) | 更好支持 JPMS |
| CI/CD | 原生支持 ${revision} 等变量 |
无缝集成 CI 流水线 |
| 构建效率 | Reactor 优化、并发构建、Maven Shell | 缩短构建时间 |
| 生命周期 | 树状结构 + before/after/all/each | 更精细的构建控制 |
| 安全性 | 全新加密系统 mvnenc | 安全存储敏感信息 |
| 迁移支持 | 提供 Upgrade Tool | 平滑过渡 |
❗ 注意事项(给开发者的建议)
- JDK 17 是必须的:虽然你可以编译低版本 Java,但运行 Maven 本身需要 JDK 17。
- 不要依赖默认插件版本:Maven 4 的 Super POM 更新了默认插件版本,可能导致行为变化。建议显式指定版本。
- 检查
post-*插件绑定 :mvn clean现在会触发post-clean,确认是否符合预期。 - 插件作者注意:老插件可能因移除 Plexus DI 而失效,需迁移到 JSR-330。
- 尽早尝试 :使用
mvn --version查看是否已有预览版可用,或关注 Apache Maven 官网。
✅ 结语
Maven 4 不只是一个版本号更新,而是一次现代化重构。它解决了长期以来的技术债务,拥抱了现代 Java 开发的需求(模块化、CI/CD、性能、安全),同时通过"双 POM"策略巧妙地保护了庞大的生态系统。
如果你是企业级 Java 项目的维护者,Maven 4 值得期待;如果你是插件开发者,则需要提前做好适配准备。
📅 当前日期:2025年10月31日
⚠️ 截至目前,Maven 4 尚未正式发布稳定版,请持续关注官方公告。
如果你想了解某个具体特性的实战示例(比如如何使用 before:each 或配置多 source directory),欢迎继续提问!