返回介绍

什么是 Maven

发布于 2025-04-21 21:42:15 字数 3918 浏览 0 评论 0 收藏

Maven 是一种声明式(declarative)的构建工具,它不是定义一套用于构建项目的过程步骤,而是用保存在 pom.xml 文件中的 Project Object Model(POM,项目对象模型)来描述项目。担当重任的 Maven 插件,它们知道如何读取 POM 文件和完成任务。例如,默认的 Maven 插件可以编译代码、创建 JAR 文件、组装 WAR 文件、创建 Web 网站、为 JAR 文件生成数字签名(sign)、计算代码质量度量(code metrics)、执行单元测试、读取 Hibernate 映射文件等。使用 Maven,你所有需要做的就是告诉它源代码在哪里,需要依赖什么文件,Maven 足够聪明,它会明白接下来应该做什么。如果不用 Maven,而是使用像 Apache Ant 这样的工具,就得定义一个显式的构建过程。如前所述,Maven 采用声明式的方法来构建和测试一个项目,作为 Ant 的替代品,它很快就受到了欢迎。

注意:Maven 可以为你节约很多时间,但是你要去学习和习惯它。

获得方便的同时也需要付出一定的代价。Maven 之所以知道如何处理你的项目的源代码、配置以及单元测试,是因为它做了一些假设。首先,Maven 假设你的项目采用的是标准布局和构建生命周期。所以,在使用 Maven 之前,我们希望你确实知道了 Maven 的这些核心假设。一个假设就是对项目的定义。在 Maven 中,一个 project 是由源代码和资源组成的,每个资源与一个 artifact 对应。这个 artifact 可以是类似 JAR 或 WAR 之类的文件,不过,需要知道的一个重点就是一个项目只有一个 artifact。另一个假设是(大多数情况下)你应该使用标准的目录布局。在 pom.xml 文件中可以对 Maven 的大部分默认设置进行修改。如果你不想将源代码保存在 src/main/java 目录中,则可以在 pom.xml 中指定另一个目录。

注意:如果你不喜欢 Maven 的约定,可以考虑换个工具。

如果你喜欢 Maven,但手边的几个项目确实不能完全满足 Maven 假设的要求,也不必放弃 Ant。事实上,Maven 在现有的 Ant 构建文件中对它进行调用也提供了方便的机制。除了本章少数几个示例以外,本书的大部分示例就以 Ant 构建文件作为基础。如果你下载随书的示例代码,就会发现本章特殊的示例具有与其他章节不同的目录布局。我们研究一下这种目录结构,也就是 Maven 中所谓的标准目录布局(Standard Directory Layout)。

有关 Maven 更详细的介绍,可以阅读 Sonatype 的《Maven:The Definitive Guide》( [1] )。

Maven 的标准目录布局

理想的构建工具应该能够自动知道如何处理一套 Java 源文件。这样的系统将会具有一定的内建智能,可以让你简单地编写一定的源代码,再将简单的文件放在项目根(root)目录下,运行构建工具,再回到项目目录。构建工具会认为你的项目包含一定的 Java 源代码,你想根据它们而生成一个 JAR 文件。如果你想生成的是 WAR 文件,就应该提供一些提示,以修改构建工具的默认行为。

这种思想已经由 Maven 实现了,至少实现了一部分,因为 Maven 提供了一套严格的约定,消除了大部分常见配置的需要。这就是所谓的“约定优于配置”(convention over configuration),在过去几年中这种思想在 Ruby on Rails 之类的框架中变得非常流行,它让你即便是编写非常复杂的 Web 应用程序也不必为不计其数的配置文件而费心(第 14 章介绍的 Stripes 也采用了 Java 业界的类似方法)。约定优于配置,这也是为什么 Apple 笔记本电脑总是可以开箱即用(out of the box)的原因,也是为什么在驾驶汽车前你不用阅读它的使用手册就知道油门在右边而刹车在左边的原因。通过同样的策略(如果你已经遵守了约定),Maven 就会自动知道你的源代码、单元测试、网站文档以及配置文件都在什么地方,而不用浪费你宝贵的时间亲自告诉 Maven 这些东西都放在哪儿。例 12-1 显示了 Maven 的项目目录布局的大致样子。

例 12-1:Maven 的标准目录布局

pom. xml

每个项目都必须有一个 pom.xml 文件(即一个 POM)。本章后面的第 12.6 节将详细介绍 POM 文件。

src/

在这个子目录中保存各种源文件。

src/main/java/

将要包含在最终 artifact(JAR 文件、WAR 文件等)中的 Java 源代码位于这个目录。

src/main/resources/

这个目录包含项目需要的各种资源:非 Java 源代码、类似 log4j.properties 的东西、hibernate.cfg.xml、本地化(localization)文件以及需要发布的 Hibernate 映射文件。

src/test/java/

保存 Unit 测试代码(TestNG 或 JUnit 测试)。

src/test/resources/

保存只供测试使用的资源。

src/site/

网站文档保存目录。

target/

构建过程生成的任何东西,可以是源代码、字节码或最终的产品,都将保存在 target 目录中。因为 target 中的文件是构建过程的产物,所以可以随意删除,不应该包括在版本控制(version control)中。

还有一些其他目录,比如 src/main/webapp、src/main/config、src/main/assembly 以及 src/main/filters,这里不对它们进行过多的介绍,在充分利用 Maven 创建复杂的应用程序时,这些目录都有各自不同的用途。例如,如果我们要生成一个 WAR 文件,则 src/main/webapp 将是 Web 应用程序的文档根目录。如果我们为命令行应用程序创建一个自定义的文档包,则 src/main/assembly 目前用于保存我们将要使用的装配描述符(assembly descriptor)。例 12-1 中列举的那些目录将出现在每个 Maven 项目中,它们是 Maven 项目最低的公共约定标准。

虽然这些看起来似乎是相对简单的想法,但业界目前还没有对 Java 项目的标准目录布局之类的事达成一致。事实上,反对使用 Maven 最常见的一个理由就是人们不喜欢 Maven 约定的目录结构。其实你可以容易地自定义这种目录结构,如果你看看本书其他章节的示例代码,就会发现我们采用的也是自己的目录布局结构。这种方法也有一些缺点,例如,由于使用自定义目录布局而引起的微妙问题,有几章示例就与 Maven Hibernate3 插件并不完全兼容。所以我向你再次警告,尽可能不要试图让 Maven 适应你的项目的自定义目录布局,而是在自定义之前调整你的项目以适应 Maven 的标准目录布局。不过有些简单的区别也不会给 Maven 造成任何问题,比如将资源保存到 src/main/java 目录下,或者配置 Maven,让它把源代码保存到 src/java 目录而不是 src/main/java 目录下。就像 Maven 对源代码有一定的标准一样,它对工具生成的源代码也有一定的约定(这些代码文件最终位于 target/generated-source 目录下,它们包含在"compile source roots"列表中,所以它们将与你自己编写的代码一起进行编译)。

注意:本章的主题或者是“接受 Maven 的约定”,或者是“你将被同化。抵抗是没用的”。

如果当你读完本节后会想“嗯,我们有更好的目录布局”,非常不幸,Maven 不适合你了。如果你想试图调整一些 Maven 的核心假设,可能要花费好些天来对付一系列莫名其妙的问题。最后,Maven 跑不起来了,你将开始大声地诅咒 Maven,接着在博客上发帖子说你有多么多么地讨厌它,这一切都因为你不愿意接受 Maven 基本的假设。可能你还没有注意到,本章开始的几节都在尽可能地为你节省时间。我可以证明 Maven 为了节省了无数的时间和精力,从效率的角度来说,给了我意外的收获。但是我也看到有些人使用 Maven 的方向就是错误的,最终除了对 Maven 的不满以外,项目上一无所获。适应 Maven,而不是让 Maven 适应你。这些已经接近事实,但如果你一开始就质疑这些事实的话,受伤的就只能是你自己。

[1] http://www.sonatype.com/book/index.html.

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。