Maven 4:20年老工具的重生之路

这篇文章详细介绍了 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:compile
  • before: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:cleanafter:clean(即 post-clean)。

这是一个行为变更,可能影响现有构建脚本!


🧩 3. 新增通用生命周期阶段:alleach

阶段 作用范围 用途
each 每个子项目内部 在每个子项目的生命周期周围执行操作
all 整个项目(含所有子项目) 在整个构建周期周围执行操作
before:all 整个构建开始前 初始化全局资源
after:all 整个构建结束后 清理、报告汇总
before:each 每个子项目开始前 子项目级初始化
after:each 每个子项目结束后 子项目级清理

非常适合复杂项目的 setup/teardown 逻辑。


🔐 五、安全与性能增强

🔐 1. 全新加密系统(mvnenc)

🚀 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 平滑过渡

❗ 注意事项(给开发者的建议)

  1. JDK 17 是必须的:虽然你可以编译低版本 Java,但运行 Maven 本身需要 JDK 17。
  2. 不要依赖默认插件版本:Maven 4 的 Super POM 更新了默认插件版本,可能导致行为变化。建议显式指定版本。
  3. 检查 post-* 插件绑定mvn clean 现在会触发 post-clean,确认是否符合预期。
  4. 插件作者注意:老插件可能因移除 Plexus DI 而失效,需迁移到 JSR-330。
  5. 尽早尝试 :使用 mvn --version 查看是否已有预览版可用,或关注 Apache Maven 官网

✅ 结语

Maven 4 不只是一个版本号更新,而是一次现代化重构。它解决了长期以来的技术债务,拥抱了现代 Java 开发的需求(模块化、CI/CD、性能、安全),同时通过"双 POM"策略巧妙地保护了庞大的生态系统。

如果你是企业级 Java 项目的维护者,Maven 4 值得期待;如果你是插件开发者,则需要提前做好适配准备。

📅 当前日期:2025年10月31日

⚠️ 截至目前,Maven 4 尚未正式发布稳定版,请持续关注官方公告。


如果你想了解某个具体特性的实战示例(比如如何使用 before:each 或配置多 source directory),欢迎继续提问!

相关推荐
百锦再3 小时前
第6章 结构体与方法
android·java·c++·python·rust·go
音符犹如代码3 小时前
ArrayList常见面试题二
java·开发语言·面试·职场和发展
JanelSirry3 小时前
Java + Spring Boot + Redis技术栈,在实际使用缓存时遇到 缓存击穿、缓存穿透、缓存雪崩
java·spring boot·缓存
NO.10243 小时前
11.4八股
java·linux·数据库
天工无极3 小时前
基于Spring AI实现法律咨询AI助手
java
乐悠小码3 小时前
Java设计模式精讲---01工厂方法模式
java·设计模式·工厂方法模式
cherry--3 小时前
集合(开发重点)
java·开发语言
寻星探路3 小时前
测试开发话题10---自动化测试常用函数(2)
java·前端·python
api_180079054604 小时前
请求、认证与响应数据解析:1688 商品 API 接口深度探秘
java·大数据·开发语言·mysql·数据挖掘