2025 年底,Apache Maven 4.0 正式 GA —— 这是 Maven 自 2004 年发布 2.0 以来,20 年最大一次架构升级!
但它不是颠覆,而是进化:你现有的pom.xml几乎不用改,就能享受更智能、更简洁、更可靠的构建体验。
本文避开复杂理论,只讲 5 个你明天就能用上的实用特性,每个都配超简示例 + Maven 3 对比,轻松上手!
✅ 前提:Maven 4 要求 JDK 17+
# 检查 Maven 版本(需 ≥ 4.0.0)
mvn --version
# 输出示例:
Apache Maven 4.0.0 (...)
Maven home: /opt/maven
Java version: 17.0.12, vendor: Eclipse Adoptium
⚠️ 注意:只需 JDK 17 来运行 Maven,你仍可用
-source 8 -target 8编译 Java 8 项目!
🔑 特性 1:子模块自动发现 —— 告别 <modules> 手动列表!
问题(Maven 3)
多模块项目中,父 pom.xml 必须显式列出所有子模块:
<!-- Maven 3 父 pom.xml -->
<project>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>service</module>
<module>dao</module>
<module>web</module> <!-- 每加一个模块,就得改这里! -->
</modules>
</project>
✅ Maven 4 解法:全自动扫描!
只要满足:
- 父项目
packaging=pom - 无
<modules>或<subprojects>声明 - 子目录含
pom.xml
→ Maven 4 自动发现并构建所有子项目!
示例目录结构:
my-app/
├── pom.xml ← 父 POM(空 modules)
├── service/
│ └── pom.xml
├── dao/
│ └── pom.xml
└── web/
└── pom.xml
父 pom.xml(Maven 4):
<!-- 只需这样! -->
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<!-- ✅ 没有 <modules>! -->
</project>
💡 执行
mvn clean install→ 自动构建service,dao,web!
🔑 特性 2:父版本自动推断 —— <parent> 不再写死 version!
问题(Maven 3)
每个子模块都得重复写父版本,升级时全项目 Ctrl+H:
<!-- Maven 3 子模块 pom.xml -->
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0</version> <!-- 每次改父版本,这里都要改! -->
</parent>
✅ Maven 4 解法:省略 version!
<!-- Maven 4 子模块 pom.xml -->
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<!-- ✅ version 可删! -->
</parent>
<artifactId>service</artifactId>
Maven 4 会:
- 沿
../路径找父pom.xml - 读取其
groupId/artifactId/version - 自动填充
✅ 升级父版本?只改父 POM 一个地方!
🔑 特性 3:CI 友好变量 —— 告别 flatten-maven-plugin!
场景:动态版本(如 Git Tag)
Maven 3 需要插件 + 复杂配置:
<!-- Maven 3:繁琐的 flatten 配置 -->
<version>${revision}</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<executions>...</executions>
</plugin>
</plugins>
</build>
✅ Maven 4 解法:原生支持!
根 pom.xml:
<project>
<groupId>com.example</groupId>
<artifactId>app</artifactId>
<version>${revision}</version> <!-- ✅ 直接用变量 -->
</project>
构建时传参:
# 方式1:命令行
mvn clean install -Drevision=2.1.0
# 方式2:.mvn/maven.config(推荐 CI 用)
# 文件内容:
-Drevision=2.1.0
-Dsha1=${env.GIT_COMMIT:0:7}
✅ 生成的 JAR 名:
app-2.1.0.jar,无需额外插件!
🔑 特性 4:消费者 POM(Consumer POM)—— 瘦身依赖描述!
问题(Maven 3)
发布到 Maven Central 的 pom.xml 包含全部构建配置(插件、属性、profile),但依赖方根本不需要!
✅ Maven 4 解法:自动分离!
- 构建 POM:你写的
pom.xml(含插件、profile) - 消费者 POM:发布到仓库的
pom.xml(仅含依赖、groupId/artifactId/version)
效果对比:
| 内容 | Maven 3 发布的 POM | Maven 4 发布的 POM |
|---|---|---|
<build><plugins> |
✅ 保留 | ❌ 移除 |
<properties> |
✅ 保留 | ❌ 移除 |
<dependencies> |
✅ 保留 | ✅ 保留(已展开 BOM) |
<parent> |
✅ 保留 | ❌ 移除(内容已内联) |
✅ 依赖方解析更快、更安全;
✅ 你仍可自由在本地用复杂插件配置——发布自动“精简”。
🔑 特性 5:构建失败更智能 —— 一键 resume + 自动跳过成功模块!
Maven 3 痛点
# 构建失败在 web 模块
mvn install
# ... [ERROR] web 模块编译失败
# 想修复后重跑?必须:
mvn install -rf :web # 但 service/dao 还会重跑!
✅ Maven 4 改进:
✅ 1. 一键 resume(自动定位失败模块):
# 构建失败后,直接:
mvn -r install # 或 --resume
# → 自动从上次失败的模块开始,且**跳过已成功的模块**!
✅ 2. 部署原子性(默认开启):
- Maven 3:部分子模块成功 → 已 deploy 到仓库
- Maven 4:所有模块成功才 deploy → 避免“半成品发布”
✅ 更符合直觉,CI 流水线更可靠!
📊 Maven 3 vs Maven 4:关键差异速查表
| 功能 | Maven 3 | Maven 4 |
|---|---|---|
| 运行所需 JDK | ≥ 7 | ≥ 17 ✅ |
| 子模块声明 | 必须 <modules> |
自动发现 ✅ |
| 父版本 | 必须写 version |
可省略 ✅ |
| 动态版本 | 需 flatten 插件 |
原生支持 ${revision} ✅ |
| 发布的 POM | 含完整构建信息 | 精简为 Consumer POM ✅ |
| 构建 resume | -rf :moduleName |
-r 自动定位 ✅ |
| 多模块 deploy | 失败模块不 deploy,但成功的已 deploy | 全成功才 deploy ✅ |
🚦 升级建议(平滑迁移)
- 先不改
pom.xml:Maven 4 完全兼容 Maven 3 的4.0.0模型 - 逐步启用新特性:
- 先删
<modules>试试自动发现 - 再删子模块
<parent><version>
- 先删
- 插件检查:确保关键插件支持 Maven 4(如
maven-compiler-plugin ≥ 4.0.0-beta-3)
🔗 官方迁移指南:What's New in Maven 4
💬 结语
Maven 4 不是“重写”,而是 20 年经验的结晶——它让 Maven 更聪明、更少样板、更可靠,却依然保持“约定优于配置”的初心。
“最好的工具,是你感觉不到它存在的工具。”
Maven 4 正在朝这个方向迈出坚实一步。
你准备升级了吗?欢迎留言分享你的迁移经验 👇
