自2010年Maven 3发布以来,这款经典Java构建工具的核心设计理念几乎没有发生过颠覆性的变化。然而,在这过去的十五年间,软件开发的技术环境早已今非昔比:
- 模块化成为项目标配
- 并行构建成为提升效率的刚需
- 云原生与容器化成为主流的交付形态
- JDK自身也以一年两个大版本的节奏高速迭代
相比之下,稳定了十多年的Maven 3,在面对现代开发需求时,不免显得有些步履蹒跚。即将到来的Maven 4,其核心目标正是解决这些长期积累的历史包袱与架构瓶颈。
虽然Maven 4仍未公布确切的GA发布日期,但目前项目已经迭代到了第五个发布候选版本(RC5)。从项目的成熟度与变更的稳定性来看,距离正式发布已经相当接近。
现在,正是开发者提前了解、评估并为未来升级做准备的黄金窗口期。
POM 模型升级:从 4.0.0 到 4.1.0
Maven 4 将POM的模型版本升级为 4.1.0,这是一个标志性的变化:
<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>
这里有几点需要注意:
- 向后兼容:Maven 4 引擎依然能够正常构建基于 4.0.0 模型的老项目。
- 新能力限制:Maven 4 引入的诸多新特性,仅对声明了 4.1.0 的 POM 生效。
- 可选声明:理论上,你可以省略
modelVersion,Maven 会从 XML Schema 中自动推导。
简而言之,这意味着 不升级你的POM文件也能使用Maven 4,但只有将模型版本升级到4.1.0,才能解锁并享受到新版本带来的全部红利。
Build POM / Consumer POM 分离:根治“POM污染”
这是 Maven 4 最重要、最具颠覆性的改进之一,旨在解决一个由来已久的痛点。
在 Maven 3 时代,我们发布到中央仓库或私有仓库的POM文件,是一个包含了“构建配方”和“依赖声明”的混合体。它既包含了插件配置、构建参数、父POM引用和各种属性,也包含了依赖信息。当其他项目引用它时,构建工具不得不解析大量与其自身构建完全无关的噪音信息。
Maven 4 的解决方案是 POM 扁平化(Flattening),并正式引入了两种POM的区分:
| 类型 |
用途 |
| Build POM |
项目自身进行构建时使用的完整POM。 |
| Consumer POM |
发布到仓库,提供给其他项目作为依赖使用的、经过清理和精简的POM。 |
Consumer POM 具备以下特征,使其变得极其“干净”:
- 不包含任何插件配置。
- 不包含父POM引用(已被解析并合并)。
- 不包含任何未实际使用的依赖(例如,scope为
test、provided的依赖在Consumer POM中会被移除)。
- 只保留真实的传递性依赖。
- 所有属性(
${})都已被解析为具体的值。
开启此功能非常简单:
mvn clean install -Dmaven.consumer.pom.flatten=true
在 Maven 3 时代,实现类似效果需要依赖第三方的 Flatten Maven Plugin。在 Maven 4 中,它已经变成了开箱即用的原生核心能力。
这一改变直接带来的好处是:依赖解析速度更快、构建过程更干净、传递性依赖的预测性更强,极大地优化了大型项目下的构建体验。
新 Artifact Type:显式控制 classpath 与 module path
Java 9引入模块系统后,类路径的管理变得更加复杂。在 Maven 3 中,规则是隐式的:
- 普通的 JAR 包 → 放在 classpath。
- 包含
module-info.class 的 JAR 包 → 自动推断并放在 module path。
这种隐式推断在复杂的模块化项目中有时不够清晰,容易引发混淆。Maven 4 新增了明确的依赖类型,让开发者可以显式声明一个依赖应该放在哪里:
<type>classpath-jar</type>
<type>module-jar</type>
更重要的是,Maven 4 专门为注解处理器(Annotation Processor)新增了类型,以更精确地管理其类路径。这对于 Lombok、MapStruct 等工具尤为重要:
processor
classpath-processor
modular-processor
以 Lombok 为例,在 Maven 4 中可以这样清晰配置:
<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> <!-- 作为编译期API使用 -->
</dependency>
</dependencies>
Maven 4 明确区分了 API classpath 与 processor classpath,使得构建语义极度清晰,也为后续的构建工具链优化打下了坚实基础。
Modules 改名为 Subprojects:为 Java 9+ “让路”
Java 9 引入的“Java Platform Module System (JPMS)”带来了“模块(Module)”的概念。这导致在同一个技术栈中出现了两个极易混淆的“模块”:
- Maven Modules:指多模块项目中的一个子模块。
- Java Modules:指JPMS中的模块。
这种同名异义的情况长期困扰着新手,也让一些工具支持变得复杂。Maven 4 选择从根源上解决这个问题:
- 改名:将 POM 中表示子模块的
modules 元素更名为 subprojects。
- 兼容:旧的
modules 元素将被标记为已弃用(deprecated),但仍能工作。
<subprojects>
<subproject>project-a</subproject>
<subproject>project-b</subproject>
</subprojects>
除了更名,Maven 4 在多项目管理上也有一系列增强:
- Parent 推断:允许空的
<parent /> 元素,Maven 会自动从目录结构中推断。
- 子项目自动发现:在特定模式下,无需在父POM中显式声明所有子项目。
- 统一构建时间戳:确保多模块项目中的所有产物共享同一个构建时间戳。
- 安全发布:如果某个子项目发布失败,整个发布流程会安全回滚,防止产生不一致的仓库状态。
这是一次从语义层面到工程实践层面的双重升级。
树形生命周期:并行构建终获“名分”
Maven 3 的生命周期本质上是线性的,即使在多模块项目中,构建阶段也是一个接一个顺序执行,并行能力有限且复杂。
Maven 4 引入了 Tree-based Lifecycle(树形生命周期),彻底改变了游戏规则:
- 每个子项目(subproject)都可以独立地在自己的生命周期中推进。
- 只要一个子项目的依赖项就绪,它的构建任务就可以立即启动,无需等待其他无关模块。
- 这对于大型多模块项目而言,意味着构建速度可以得到显著的、质的提升。
启用树形生命周期构建模式只需一个简单的命令:
mvn -b concurrent verify
配置能力显著增强的“小”变化
除了上述重大革新,Maven 4 还包含许多提升开发体验的增强。
1. 条件表达式 Profile
Profile 的激活条件不再局限于 os.name、jdk 等几个简单属性,而是引入了一个功能强大的表达式系统,支持文件存在性检查、字符串操作等复杂逻辑。
<condition>exists('${project.basedir}/src/**/*.xsd') && length(${user.name}) > 5</condition>
2. 统一的 Sources 模型
Maven 3 使用分散的元素定义源码目录:
<sourceDirectory>...</sourceDirectory>
<testSourceDirectory>...</testSourceDirectory>
Maven 4 将其统一为一个更灵活、更强大的 sources 模型:
<sources>
<source>
<scope>main</scope>
<directory>my-custom-dir/foo</directory>
</source>
<source>
<scope>test</scope>
<directory>my-custom-dir/bar</directory>
</source>
</sources>
这种模型特别适合管理多源码目录、多版本共存、模块化项目等复杂场景,也减少了对Maven插件配置的依赖。
升级辅助工具
为了帮助开发者平滑过渡,Maven 4 将提供一个官方的升级分析工具:
mvnup check # 仅分析项目并生成升级评估报告
mvnup apply # 根据报告,自动应用推荐的修改
这个工具会扫描你的项目,分析POM结构、插件兼容性、项目布局等,然后给出具体、可执行的升级建议,大大降低了迁移成本和风险。
Maven 4 的这次“彻底重构”并非简单的版本号跃进,而是一次针对现代Java开发生态的全方位适配。从构建性能、依赖管理、模块化支持到配置灵活性,它都带来了切实的改进。对于长期被Maven 3性能或复杂性所困扰的团队,尤其是那些拥有大型多模块项目的团队,Maven 4 无疑是一个值得期待和规划的升级方向。
你对Maven 4的哪个新特性最感兴趣?不妨在云栈社区的开发者板块与大家一同讨论。