认识Maven

《认识Maven》源站链接,阅读体验更佳~
构建是每个程序员每天都在做的工作,因为这是让我们的代码跑起来的必经之路。如果你对自己的工作做一个大体的总结,可能会发现我们每天的工作,除了编写源代码之外,我们每天可能有相当一部分事件会花费在编译、测试、生成报告,再到打包、部署等繁琐且不起眼的工作上,而这些就是构建。

如果我们不借助任何工具,完全依靠手动去进行这些构建相关的工作,那我们花费在构建上的时间有可能比真正编码的时间都要多。

就以Java来说,在不使用构建工具的情况下我们就只能使用JDK Tools中提供的各种工具来手动进行构建。如果项目简单还好,但是Java是开源的,我们在实际的项目中几乎不可能只依赖JDK编写代码,或多或少的都会依赖第三方的类库;这个时候我们如果手动使用JDK Tools中提供的工具来进行项目的构建麻烦就大了——我们要设置各种选项,传递各种参数…没等项目构建好呢,人就已经被重构了…

另外,我们还要面临的问题是项目中依赖的管理,各种依赖之间的关系错综复杂,光要找全所有的依赖可能就得花费很大的功夫,更何况我们还要应对可能出现的依赖冲突的问题。

最重要的——项目的构建并不是一次性的,而是一个需要不断重复的动作,想想就令人头大。

Java构建工具发展史

‘懒惰’是程序员的美德,对于需要不断重复进行的动作,我们就要想办法用程序处理,所以构件工具也就应运而生。

Maven不是Java领域唯一的构建管理的解决方案。这里我们先介绍其他构建解决方案,并将它们与Maven进行比较。

  • Make

    make是比较老牌的构建管理工具,现在的C/C++语言使用make工具进行构建仍然是主流。最早的时候,Java也是使用make工具进行构建,Make由一个名为Makefile的脚本文件驱动,该文件使用Make自己定义的语法格式。其基本组成部分为一系列规则(Rules),而每一条规则又包括目标(Target)、依赖(Prerequisite)和命令(Command)。Makefile的基本结构如下:

    makefile的基本结构

    Make通过一系列目标和依赖将整个构建过程串联起来,同时利用本地命令完成每个目标的实际行为。Make的强大之处在于它可以利用所有系统的本地命令,尤其是UNIX/Linux系统,丰富的功能、强大的命令能够帮助Make快速高效地完成任务。

    但是,Make将自己和操作系统绑定在一起了。也就是说,使用Make,就不能实现(至少很难)跨平台的构建,这对于Java来说是非常不友好的。此外,Makefile的语法也成问题,很多人抱怨Make构建失败的原因往往是一个难以发现的空格或Tab使用错误。

  • Ant

    Ant不是指蚂蚁,而是意指“另一个整洁的工具”(Another Neat Tool),它最早用来构建著名的Tomcat,其作者James Duncan Davidson创作它的动机就是因为受不了Makefile的语法格式。我们可以将Ant看成是一个Java版本的Make,也正因为使用了Java,Ant是跨平台的。此外,Ant使用XML定义构建脚本,相对于Makefile来说,这也更加友好。

    与Make类似,Ant有一个构建脚本build.xml,如下所示:

    Ant build.xml

    build.xml的基本结构也是目标(target)、依赖(depends),以及实现目标的任务。比如在上面的脚本中,jar目标用来创建应用程序jar文件,该目标依赖于compile目标,后者执行的任务是创建一个名为classes的文件夹,编译当前目录的java文件至classes目录。compile目标完成后,jar目标再执行自己的任务。Ant有大量内置的用Java实现的任务,这保证了其跨平台的特质,同时,Ant也有特殊的任务exec来执行本地命令。

  • Gradle

    Gradle继承了Maven约定优于配置的思维,但是它定制起来更加简单。使用Gradle可以直接使用基于Maven的坐标机制,我们可以认为Gradle是Maven的下一代构建工具,但是我们这个系列的文章是用来介绍Maven的,而对于Gradle的介绍会有专门的系列文章来进行,所以这里我们就不对Gradle进行过多的介绍了。

Maven的优势

Maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”,它的主要用途之一就是用于服务的构建。

我们上面所介绍的Java构建工具无论是Make还是Ant,都是过程式的,它们其实都是一种更高维度上的脚本工具,项目构件的所有流程都是由我们自定义的,我们显式地指定每一个目标,以及完成该目标所需要执行的任务。针对每一个项目,开发者都需要重新编写这一过程,这里其实隐含着很大的重复。

我们发现,这样的重复是没有必要的,对于项目构建这件事来说,所有项目的构建过程都是类似的,基于这一点,Maven抽象了一个完整的构建生命周期模型,这个模型吸取了其他诸多构建脚本和构建工具的优点,总结了大量项目的实际需求。如果遵循这个模型,我们可以在最大程度上消除构建的重复,同时可以避免很多构建过程中不必要的错误。

并且,Maven采用来插件机制来实现构建的过程,每一个Maven任务都是由插件来实现的,我们可以直接使用大量优秀成熟的Maven插件来完成我们的任务(很多时候我们可能都意识不到自己正在使用Maven插件)。此外,如果我们有自己独特的需求,我们也可以轻松实现自己的插件。

**通过抽象出构建的生命周期和采用插件机制,maven成功把构建过程从命令式变成了声明式——项目的整体构建过程是约定好了的,项目构建过程和过程各个阶段所需的工作都由插件实现,并且大部分插件都是现成的,开发者只需要声明项目的基本元素,Maven就执行内置的、完整的构建过程。**这很像我们编码中经常使用的模板方法模式,构建的生命周期就是整个算法的模板,而每一个插件则是算法中某个步骤的具体实现。这在最大程度上消除重复的同时为我们提供了比较好的扩展性。

使用Maven之后,我们的构建过程将变得自动化,从清理、编译、运行测试用例、生成报告,再到打包和部署,我们不需要也不应该一次又一次地输入命令。如果使用了Maven,我们需要做的将是用Maven配置好项目的构建过程,然后输入简单的命令,例如mvn clean install,Maven就会自动帮我们处理这些琐碎的任务。

同时,Maven是跨平台的,这意味着无论是在Windows上,还是在Linux或者是MacOS上,我们只要配置好项目的构建过程之后,就可以使用同样的简单的命令来进行项目的构建。

Maven不仅仅是构建工具

Maven不仅仅是一个构建工具,它同时还是一个依赖管理工具和项目信息管理工具,并且它提供了中央仓库,能够帮助我们寻找和获取我们所需要的构件。

在这个开源的时代,几乎任何Java应用都会借用一些第三方的开源类库,这些类库都可以通过依赖的方式引入我们的项目中。如果我们手动对这些依赖进行管理,我们就需要手动去下载这些开源类库,并且在项目中建立专门的目录进行管理,而在构建的时候也需要将这些依赖考虑在内。随着依赖的增多,版本冲突、依赖冲突等问题就会接踵而至,手工解决这些依赖问题是十分枯燥且容易出错的。

幸运的是,Maven为依赖管理提供了一个优秀的解决方案,它通过一个坐标系统准确地定位每一个构件(artifact),也就是通过一个坐标,Maven可以找到任何一个Java类库(比如jar文件)。Maven给这个类库世界引入了经纬度,让他们变得有秩序,于是我们可以借助它来有序地管理依赖,轻松地解决那些繁杂的依赖问题。

Maven还为全世界的Java开发者提供了一个免费的中央仓库,在其中可以找到几乎所有的流行开源类库。通过一些Maven的衍生工具(如Nexus),我们还可以对仓库进行快速的搜索。只要定位了坐标,Maven就能够帮我们自动下载,省去了手工劳作。

同时,Maven还提供了项目模块化的能力,它能帮助我们管理原本分散在项目各个角落中的项目信息,包括项目描述、开发者列表、版本控制系统地址、许可证、缺陷管理系统地址等。这些微小的信息看起来很琐碎,并不起眼,但是却在不知不觉中帮我们节省了大量寻找信息的时间。除了直接的项目信息,通过Maven自动生成的站点,以及一些已有的插件,我们还可以轻松地获取到项目的测试报告、静态分析报告、源码版本日志报告等许多非常具有价值的项目信息。

总结

Maven是一个非常强大的构建工具,它抽象出了项目构建的生命周期,帮助我们标准化构建过程。在Maven之前,十个项目可能有十种构建方式,而如果我们使用了Maven,所有项目的构建命令都是单一一致的,这极大避免了不必要的学习成本,而且有利于促进项目团队的标准化。而Maven使用了插件机制来实现自己的功能,这也使得Maven具有将强的扩展性。

同时,Maven还是一个依赖管理工具和项目信息管理工具,Maven通过一个坐标系统准确地定位每一个构件,并且为全世界的Java开发者提供了一个免费的中央仓库,在其中可以找到几乎所有的流行开源类库。

上面介绍了那么多,其实Maven的最终目的和Make以及Ant并没有太大的区别,不管是提供依赖管理功能,模块化的功能还是项目信息管理的功能,其最终的目的还是为了简化我们项目的构建。那么其实现编译、打包等动作的基本原理和Make已经Ant其实也是一样的,那就是对JDK Tools中的命令工具进行包装。

只不过Maven抽象出构建的声明周期以及采用插件机制来实现的方式将这些JDK底层的工具完全隐藏了起来,使得我们在使用Maven的时候感觉不到自己正在使用JDK Tools中的工具。

maven是基于pom.xml文件的,我们在pom.xml文件中配置项目信息、项目的依赖、项目的构建步骤等信息,然后我们使用maven所提供的命令来进行项目的构建。当我们运行某一个maven命令,maven就会根据生命周期来运行一系列的JDK Tools中的命令和一系列Maven插件(当然,JDK Tools中工具的使用也是由Maven插件来进行的),来帮我们完成构建过程,当然实际所发生的可能要复杂的多。

因此,在我们学习使用Maven构建我们的项目之前,首先需要学会的就是如何使用Maven来管理我们项目的依赖,所以,我们下一篇文章就来介绍一下Maven中构件的坐标和依赖。

以上就是我对Java项目构建工具以及Maven的基本理解,感谢你耐心读完,本人深知技术水平和表达能力有限,如果文中有什么地方不合理或者你有其他不同的思考和看法,欢迎随时和我进行讨论(laomst@163.com)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

劳码识途

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值