Maven 4 终于来了!Java 构建工具史诗级更新,十年磨一剑!

Maven 4 带来 POM 分离、并发构建、子项目重命名、注解处理器简化等重大更新,全面提升 Java 项目构建效率与清晰度。

如果你还在用 Maven 3,那你真的该看看这篇了!Maven 4 已经正式进入 RC5(Release Candidate 5)阶段,尽管 Apache 官方还没官宣 GA(General Availability)正式版日期,但这次更新堪称近十年来最重磅的 Java 构建工具革命!

Maven 自 2004 年发布以来,几乎统治了整个 Java 项目构建生态,而上一次大版本 Maven 3 还是在 2010 年推出的。

整整十五年,社区翘首以盼的 Maven 4,终于带着性能提升、语义清晰化、模块解耦、依赖管理现代化等一揽子新特性杀回来了!

POM 模型升级到 4.1.0,旧项目兼容但新功能需主动启用!

Maven 4 首先在项目对象模型(POM)上做了重大升级,将默认模型版本从沿用多年的 4.0.0 提升到了 4.1.0

你可能会问:这有什么用?

其实,这不仅是版本号的变化,更是语义模型的现代化重构。新版本的 POM 命名空间变成了 http://maven.apache.org/POM/4.1.0,XSD 也相应更新。

好消息是,Maven 4 完全向下兼容 4.0.0 的 POM 文件,你现有项目不用改也能直接构建。但如果你希望用上 Maven 4 的新特性——比如子项目自动发现、更清晰的依赖结构、或者新的 artifact 类型——那就必须主动把 modelVersion 改成 4.1.0。

有趣的是,现在 modelVersion 元素甚至可以省略,Maven 会根据 xmlns 自动推断出模型版本,大大减少了样板代码。不过建议还是显式写上,提高可读性。升级非常简单,只需在你的根 pom.xml 顶部加上:

<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 新世界大门的钥匙!

构建 POM 与消费者 POM 分离,彻底解决依赖“信息污染”!

这是 Maven 4 最具革命性的改动之一!

在 Maven 3 时代,当你把一个库发布到仓库(比如 Maven Central),它的 POM 文件里不仅包含对外暴露的依赖信息,还塞满了内部构建细节:插件配置、父 POM 引用、甚至是测试依赖!这导致下游项目在解析依赖时,不仅要下载无用的元数据,还可能因为父 POM 不存在而构建失败。

Maven 4 彻底解决了这个问题——它引入了“构建 POM”(Build POM)和“消费者 POM”(Consumer POM)的分离机制。

构建 POM 还是你写在本地的完整 pom.xml,而当你执行 install 或 deploy 时,Maven 会自动生成一个精简版的 Consumer POM,只保留真正对外公开的信息:使用的传递依赖、依赖管理(dependencyManagement)中实际被引用的部分,并且所有属性(properties)都会被内联展开(resolved in place)。

这个过程叫做“扁平化”(flattening)。

过去你需要引入 Flatten Maven Plugin 才能实现,现在 Maven 4 的 install-plugin 和 deploy-plugin 原生支持!只需在命令行加上 -Dmaven.consumer.pom.flatten=true,比如:mvn clean install -Dmaven.consumer.pom.flatten=true。

从此,你的依赖库干净、安全、无副作用,下游用户再也不用被你的内部构建逻辑“绑架”了!

全新 Artifact 类型登场,Java 模块化与注解处理器配置革命!

Maven 4 对 artifact(构件)类型进行了重大扩展,让 Java 模块化(JPMS)和注解处理器(如 Lombok)的配置变得前所未有的简单。

过去,Maven 会根据 JAR 包是否包含 module-info.class 自动判断它是普通类路径 JAR 还是模块路径 JAR。但在复杂项目中,这种自动判断常常出错。Maven 4 引入了两个显式类型:classpath-jarmodule-jar,让你手动控制 JAR 的归属路径,彻底告别猜测。

更炸裂的是对注解处理器的支持!以前用 Lombok,你得在 maven-compiler-plugin 里配置 processorPaths,不仅繁琐还容易出错。现在 Maven 4 新增了 processorclasspath-processormodular-processor 三种类型。

你只需要在 dependencies 里声明一次,Maven 就会自动把它放到编译器的处理器路径上!举个例子,用 Lombok 的新写法:

<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>

注意这里用了两个依赖:一个用 type 指定为处理器,另一个用 provided scope 提供 API。Maven 4 会自动将它们分配到正确的编译类路径和处理器类路径。未来,Maven 还可能扩展更多类型,比如用于 Javadoc 的 taglet 或 doclet 路径,构建系统将越来越“懂”Java!

“模块”改名“子项目”,Maven 4 终于理清 Java 多模块项目命名混乱!

Java 开发者是不是经常被“Maven 模块”和“Java 模块”搞晕?Maven 3 的 modules 元素和 Java 9 的 module-info.java 名字冲突,造成大量混淆。

Maven 4 干脆一锤定音:把 modules 改名为 subprojects(子项目)
现在你在 POM 里写的是 而不是 ,语义更清晰,彻底和 Java 的模块系统划清界限。

同时,Maven 4 还带来一系列子项目体验优化:

第一,父 POM 自动推断——你可以在子项目的 POM 里写一个空的 ,Maven 会自动从聚合 POM(aggregator POM)中继承坐标,省去重复配置;

第二,子项目自动发现——如果你的项目结构规整(每个子文件夹都有 pom.xml),甚至可以完全省略 元素,Maven 会自动扫描并加载所有子项目,类似 Gradle 的 includeFlat 行为;

第三,打包一致性增强——所有子项目生成的 jar/war 等归档文件,内部时间戳统一为构建开始时间,确保可重现构建(reproducible builds);

第四,安全部署机制——如果一个多模块项目中任意一个子项目构建失败,整个部署流程会立即中断,避免部分成功部分失败的“半成品”被推送到仓库,极大提升发布可靠性。

这些改动看似细节,实则大幅提升了大型项目的维护效率和构建稳定性。

构建生命周期全面重构,支持并发构建与精细钩子控制!

Maven 4 对核心构建生命周期(lifecycle)做了底层重构,引入了树形生命周期模型(tree-based lifecycle),彻底改变了多模块项目的构建方式。

在 Maven 3 中,所有模块按顺序或简单并行执行,依赖关系处理粗放。Maven 4 则让每个子项目独立推进自己的生命周期阶段,只有当它的依赖项目达到“就绪”状态(ready phase)后,才会触发构建。这不仅显著提升多项目构建性能,还让依赖顺序更符合直觉。开启并发构建只需加一个参数:mvn -b concurrent verify。

更强大的是,Maven 4 为每个生命周期阶段都增加了 before:after: 钩子(hooks)。

比如,你想在 install 阶段之前执行 GPG 签名,过去只能绑定到 verify 阶段(语义错误),现在可以直接写 before:install。
after: 钩子只有在主阶段成功时才执行,避免了失败后误操作。
此外,还新增了 alleach 两个虚拟阶段:all 钩子在整个项目树开始/结束时运行一次(适合全局初始化/清理),each 钩子则在每个子项目的每个阶段前后运行(适合精细化监控)。

这些钩子取代了旧版的 pre/post 命名(现在只是别名),让插件绑定逻辑更精确、可预测。对于 CI/CD 流水线或复杂发布流程,这是质的飞跃!

条件激活、源码目录重构与智能升级工具,细节体验全面拉满!

除了大功能,Maven 4 在开发者日常体验上也做了大量优化。

首先,Profile 激活更智能:现在可以用 元素写复杂逻辑表达式,比如判断某个 XSD 文件是否存在且用户名长度大于 5:

<condition>exists('${project.basedir}/src/<strong> /*.xsd') && length(${user.name}) > 5</condition>
(注意 XML 特殊字符需转义或用 CDATA)。

其次,源码目录配置彻底革新:Maven 3 只能通过

<sourceDirectory>和<testSourceDirectory>
各指定一个目录,想加多个就得靠插件。

Maven 4 引入统一的 配置块,支持任意数量的源码根目录,并可指定 scope(main/test):

<project>
  <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>

这对多发布版本(multi-release JAR)、混合模块布局等高级场景简直是福音。最后,也是最贴心的——Maven 4 内置升级工具 mvnup**!只需运行 mvnup check,它就会扫描你的整个项目,检查 POM、插件版本、结构兼容性,并生成详细的迁移建议报告;运行 mvnup apply 则直接自动修改 pom.xml 完成升级。再也不用担心手动迁移出错,Apache 这次真的把开发者体验做到了极致!

总结:Maven 4 不只是升级,而是 Java 构建范式的全面进化!

总的来说,Maven 4 远不止是 Maven 3 的小修小补,而是一次面向现代 Java 开发的全面重构。

它通过 POM 模型升级、构建/消费者分离、Artifact 类型扩展、子项目语义澄清、生命周期并发化、以及丰富的钩子和配置选项,解决了过去十几年积累的诸多痛点。

性能更强、语义更清、扩展性更好、依赖管理更安全——无论你是维护老旧单体应用,还是构建新一代模块化微服务,Maven 4 都能提供更高效、更可靠的构建体验。

虽然正式版尚未发布,但 RC5 已经足够稳定用于评估和试点。强烈建议所有 Java 团队开始测试迁移,利用内置的 mvnup 工具平滑过渡。