Maven 是一个跨平台的项目管理和构建自动化工具。但是对于我们程序员来说,我们最关心的是它的项目构建功能。
Maven 是基于项目对象模型的(POM),这个单词来自于“意第绪语(一种犹太人语言)”,意为“知识的积累”。作为Apache组织中一个颇为成功的开源项目,Maven主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。
通常我们将从拿到源码到得到最终的产品的过程(源码-->产品)叫过“构建”。这个过程一般包括编译、测试、生成文档、打包、部署等等。
在实际的工作中我们会发现,除了编写源代码,我们每天有相当一部分时间花在了编译、运行单元测试、生成文档、打包和部署等繁琐且不起眼的工作上,即所谓的“构建”上。如果现在还手工这样做,成本非常高,于是有人用软件的方法让这一系列工作完全自动化,使得软件构建可以像全自动流水线一样,只需要一条简单的命令,所有繁琐的步骤都能自动完成,很快就能得到最终结果。
Maven是一个异常强大的优秀的构建工具,能够帮我们自动化构建过程,从清理、编译、测试到生成报告,再到打包和部署。我们不用一遍遍地输入命令、点击鼠标,我们要做的是使用Maven配置好项目,然后输入简单命令(如mvnclean install),Maven会帮我们处理那些繁琐的任务。
我们一直在避免重复,设计的重复、编码的重复、文档的重复,当然还有构建的重复。Maven最大化地消除了构建重复,抽象了一个完整的构建生命周期模型,并且为绝大部分的构建任务提供了已实现的插件。如果遵循这个模型,可以避免很多不必要的错误,可以直接使用大量成熟的Maven插件来完成我们的任务。即,Maven抽象了构建过程,提供了构建任务的实现。
或者可以说Maven制定了一套标准。如果不用Maven,十个项目可能有十套构建方式;有了Maven之后,所有项目的构建命令都是简单一致的,而且Maven是夸平台的,在Windows、Linux、Mac等上的命令也都相同。这极大地促进了不必要的学习成本,而且有利于促进项目团队的标准化。
或者说Maven提倡约定优于配置(Convention Over Configuration),Maven对于项目目录结构、测试用例命名方式等内容都有既定的规则,只要遵循了这些成熟的规则,用户在项目间切换的时候就免去了额外的学习成本。
Java不仅是一门编程语言,还是一个平台。同理,Maven不仅是构建工具,还是一个依赖管理工具。它为全世界的Java开发者提供了一个免费的“中央仓库”,在其中几乎可以找到任何流行的开源类库。通过一些Maven的衍生工具(如Nexus),我们还能对其进行快速地搜索,只要定位了坐标(配置了依赖关系)Maven就能帮我们自动下载构件,省去了手工劳动。
在开源的年代,几乎任何Java应用都会借用一些第三方的开元类库,这些类库都可以通过依赖的方式引入到项目中来。随着依赖的增多、版本不一致、版本冲突、依赖臃肿等问题都会接踵而至。手工解决这些问题是十分费时费力的,幸运的是Maven提供了一个优秀的解决方案,它通过一个坐标系统准确的定位每一个构件(artifact),也就是通过一组坐标Maven能找到任何一个类库(如jar文件)。Maven给这个类库引入了经纬,让它们变得有序,于是我们可以借助它有序的管理依赖,轻松地解决那些繁杂的依赖问题。
上面说到Maven 坐标能够确定一个构件。换句话说,我们可以用它来解决依赖关系。在 POM 中,groupId,artifactId, packaging, version 叫作 maven 坐标,它能唯一的确定一个构件。有了 maven 坐标,我们就可以用它来指定我们的项目所依赖的其他项目,插件,或者父项目。一般 maven 坐标写成如下的格式: groupId:artifactId:packaging:version
在 POM 中,依赖关系是在 dependencies 部分中定义的。例如,我们用dependencies 定义对于 junit 的依赖:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies>
Maven还能帮助我们管理原本分散在项目中各个角落的项目信息,包括项目描述、开发者列表、版本控制系统地址、许可证、缺陷管理系统地址等。这些微小的变化看起来很琐碎,并不起眼,但却在不知不觉中为我们节省了大量寻找信息的时间。除了直接的项目信息,通过Maven自动生成的站点,以及一些已有的插件,我们还能够轻松获得项目文档、测试报告、静态分析报告、源码版本日志报告等非常具有价值的项目信息。
Make也许是最早的构建工具,它由一个名为Makefile的脚步文件驱动。它的强大之处在于它可以利用所有系统的本地命令,尤其是Unix、Linux系统,丰富的功能强大的命令能够帮助Make快速高效的完成任务。但是Make将自己和操作系统绑定在一起了,也就是说,使用Make将不能(至少很难)跨平台构建。而且Makefile的语法也很有问题,很多人抱怨Make构建失败的原因,往往是一个难以发现的空格或Tab使用错误。
Ant(另一个整洁的工具-Another Neat Tool)最早用来构建著名的Tomcat。与Make一样,都是过程式的,开发者显式地指定每一个日标,以及完成该目标所需要执行的任务。针对每一个项目,开发者都需要重新编写这一过程,这里其实隐含着很大的重复。Maven是声明式的,项目构建过程和过程各个阶段所需的工作都由插件实现,并且大部分插件都是现成的,开发者只需要声明项目的基本元素,Maven就执行内置的、完整的构建过程。这在很大程度上消除了重复。此外,Ant本身是没有依赖管理的,幸运的是,Ant用户现在可以借助lvy管理依赖。而对于Maven用户来说,依赖管理是理所当然的,Maven不仅内置了依赖管理,更有一个可能拥有全世界最多Java开源软件包的中央仓库,Maven用户无需任何配置就可以无偿享用。
Maven 是一个基于项目对象模型(POM)的,提倡约定优于配置(ConventionOver Configuration)的,跨平台的项目管理和构建自动化工具。首先它是一个优秀的构建工具(构建自动化、消除构建重复、标准化构建过程),其次它还是一个依赖管理工具、项目信息管理工具。