有人能告诉我Ant和Maven之间的区别吗?我也没用过.我知道他们习惯于自动构建Java项目,但我不知道从哪里开始.
在Maven:The Definitive Guide中,我在介绍标题为"Ant和Maven之间的差异"的部分标题中写了Maven和Ant之间的区别.这是一个答案,它是该介绍中的信息与一些附加说明的组合.
一个简单的比较
我只是向您展示这一点,以说明在最基本的层面上,Maven有内置的约定.这是一个简单的Ant构建文件:
simple example build file
在这个简单的Ant示例中,您可以看到如何告诉Ant确切的操作.有一个编译目标,其中包括将src/main/java目录中的源编译为target/classes目录的javac任务.您必须告诉Ant您的源的确切位置,您希望存储结果字节码的位置,以及如何将此全部打包到JAR文件中.虽然最近的一些开发有助于减少Ant的程序性,但开发人员使用Ant的经验是编写用XML编写的过程语言.
将前一个Ant示例与Maven示例进行对比.在Maven中,要从某个Java源创建JAR文件,您需要做的就是创建一个简单的pom.xml,将源代码放在$ {basedir}/src/main/java中,然后从命令行运行mvn install .示例Maven pom.xml实现了相同的结果.
4.0.0 org.sonatype.mavenbook my-project 1.0
这就是你在pom.xml中所需要的.从命令行运行mvn install将处理资源,编译源代码,执行单元测试,创建JAR,并将JAR安装在本地存储库中,以便在其他项目中重用.无需修改,您可以运行mvn site,然后在target/site中找到包含JavaDoc链接的index.html文件以及一些有关源代码的报告.
不可否认,这是最简单的示例项目.一个只包含源代码并生成JAR的项目.遵循Maven约定的项目,不需要任何依赖项或自定义.如果我们想要开始自定义行为,我们的pom.xml将会增加大小,在最大的项目中,您可以看到非常复杂的Maven POM的集合,其中包含大量的插件定制和依赖声明.但是,即使您的项目的POM文件变得更加丰富,它们也会使用Ant从类似大小的项目的构建文件中获取完全不同类型的信息.Maven POM包含声明:"这是一个JAR项目","源代码在src/main/java中".Ant构建文件包含显式指令:"这是项目","源代码src/main/java
","运行javac
此目录","将结果放入target/classses
","从......创建JAR"等.必须明确关于这个过程,有一些东西"内置"到Maven只知道源代码在哪里以及如何处理它.
高级别比较
在这个例子中Ant和Maven之间的区别?蚂蚁...
没有像常见项目目录结构那样的正式约定,你必须告诉Ant到哪里找到源以及放置输出的位置.非正式的惯例随着时间的推移而出现,但它们尚未被编入产品中.
是程序性的,你必须告诉Ant究竟该做什么以及何时做.你必须告诉它编译,然后复制,然后压缩.
没有生命周期,你必须定义目标和目标依赖.您必须手动将一系列任务附加到每个目标.
Maven的地方......
有约定,它已经知道你的源代码在哪里,因为你遵循约定.它将字节码放在目标/类中,并在目标中生成一个JAR文件.
是陈述性的.您所要做的就是创建一个pom.xml文件并将您的源代码放在默认目录中.Maven负责其余的工作.
有一个生命周期,你执行时调用它mvn install
.该命令告诉Maven执行一系列序列步骤,直到它到达生命周期.作为整个生命周期之旅的副作用,Maven执行了许多默认的插件目标,这些目标可以编译和创建JAR.
常春藤怎么样?
是的,所以像Steve Loughran这样的人会阅读这种比较并称之为犯规.他将谈论答案如何完全忽略了一个名为Ivy的东西,以及Ant可以在最近的Ant版本中重用构建逻辑这一事实.这是真的.如果你有一群聪明的人使用Ant + antlibs + Ivy,你最终会得到一个设计精良的版本.尽管如此,我非常确信Maven是有道理的,我很乐意将Ant + Ivy与一个拥有非常敏锐的构建工程师的项目团队一起使用.话虽如此,我认为你最终会错过许多有价值的插件,比如Jetty插件,并且你最终会做一大堆你不需要做的工作.
比Maven和Ant更重要
您是否使用Repository Manager来跟踪软件工件.我建议下载Nexus.您可以使用Nexus代理远程存储库,并为您的团队提供部署内部工件的位置.
您有适当的软件组件模块化.一个巨大的整体组件很少随着时间的推移而扩展.随着项目的发展,您将拥有模块和子模块的概念.Maven非常适合这种方法.
您为构建采用了一些约定.即使您使用Ant,您也应该努力采用与其他项目一致的某种形式的约定.当一个项目使用Maven时,这意味着任何熟悉Maven的人都可以选择构建并开始运行它,而不必为了弄清楚如何编译这个东西而无需进行配置.
Maven是一个框架,Ant是一个工具箱
Maven是预制的公路车,而Ant是一组汽车零件.使用Ant,您必须自己制造汽车,但至少如果您需要进行任何越野驾驶,您可以制造正确类型的汽车.
换句话说,Maven是一个框架,而Ant是一个工具箱.如果你满足于在框架范围内工作,那么Maven会做得很好.对我来说问题是我不断碰到框架的界限,它不会让我失望.
XML详细程度
tobrien是一个对Maven了解很多的人,我认为他对这两种产品进行了非常好的,诚实的比较.他将一个简单的Maven pom.xml与一个简单的Ant构建文件进行了比较,并提到了Maven项目如何变得更加复杂.我认为值得看一下你在一个简单的真实项目中更有可能看到的几个文件的比较.下面的文件代表多模块构建中的单个模块.
首先,Maven文件:
com.mycompany app-parent 1.0 4.0.0 persist Persistence Layer com.mycompany common compile ${project.version} com.mycompany domain provided ${project.version} org.hibernate hibernate ${hibernate.version} provided commons-lang commons-lang ${commons-lang.version} provided org.springframework spring ${spring.version} provided org.dbunit dbunit 2.2.3 test org.testng testng ${testng.version} test jdk15 commons-dbcp commons-dbcp ${commons-dbcp.version} test com.oracle ojdbc ${oracle-jdbc.version} test org.easymock easymock ${easymock.version} test
和等效的Ant文件:
tobrien用他的例子来证明Maven有内置的约定,但这并不一定意味着你最终会编写更少的XML.我发现事实恰恰相反.pom.xml比build.xml长3倍,并且不会偏离约定.事实上,我的Maven示例显示没有额外的54行配置插件.那个pom.xml是一个简单的项目.当您开始添加额外需求时,XML确实开始显着增长,这对于许多项目来说并不是不寻常的.
但你必须告诉Ant该做什么
上面我的Ant示例当然不完整.我们仍然必须定义用于清理,编译,测试等的目标.这些目标是在多模块项目中的所有模块导入的公共构建文件中定义的.这让我想到了如何在Ant中明确地编写所有这些内容,而在Maven中它是声明性的.
它的确如此,如果我不必明确地编写这些Ant目标,它将节省我的时间.但是多少时间?我现在使用的常见构建文件是我5年前编写的文件,此后只进行了细微的改进.在我使用Maven进行了2年的实验之后,我将旧的Ant构建文件从机柜中取出,将其掸掉并将其重新投入使用.对我来说,必须明确告诉Ant做什么的成本在5年内增加了不到一周.
复杂
我要提到的下一个主要差异是复杂性和它具有的现实效果.构建Maven的目的是减少负责创建和管理构建过程的开发人员的工作量.为了做到这一点,它必须是复杂的.不幸的是,复杂性往往会否定其预期目标.
与Ant相比,Maven项目中的构建人员将花费更多时间:
阅读文档:有关Maven的更多文档,因为您需要学习更多内容.
教育团队成员:他们发现找一个知道而不是试图自己找答案的人更容易.
构建故障排除:Maven不如Ant可靠,尤其是非核心插件.此外,Maven构建不可重复.如果您依赖于插件的SNAPSHOT版本,这很可能,您的构建可能会在您没有更改任何内容的情况下中断.
编写Maven插件:插件通常是在编写特定任务时编写的,例如创建一个webstart包,这使得将其重用于其他任务或将它们组合以实现目标变得更加困难.因此,您可能必须编写自己的一个来解决现有插件集中的工作差距.
相反:
Ant文档简洁,全面,并且集中在一个地方.
Ant很简单.尝试学习Ant的新开发人员只需要了解一些简单的概念(目标,任务,依赖项,属性),以便能够找出他们需要知道的其余内容.
蚂蚁是可靠的.在过去的几年中,Ant的发布并不多,因为它已经有效了.
Ant构建是可重复的,因为它们通常是在没有任何外部依赖性的情况下创建的,例如在线存储库,实验性第三方插件等.
Ant很全面.因为它是一个工具箱,所以您可以组合这些工具来执行您想要的几乎任何任务.如果您需要编写自己的自定义任务,那么操作起来非常简单.
熟悉
另一个区别是熟悉度.新开发人员总是需要时间来加快速度.熟悉现有产品有助于这方面,Maven支持者正确地声称这是Maven的好处.当然,Ant的灵活性意味着您可以创建自己喜欢的任何约定.所以我使用的约定是将源文件放在目录名src/main/java中.我编译的类进入名为target/classes的目录.听起来很熟悉不是吗.
我喜欢Maven使用的目录结构.我认为这是有道理的.他们的构建生命周期.所以我在Ant构建中使用相同的约定.不仅因为它有意义,而且因为以前使用过Maven的人都会熟悉它.
Ant主要是一个构建工具.
Maven是一个项目和依赖项管理工具(当然也可以构建您的项目).
如果你想避免使用Maven,Ant + Ivy是一个非常好的组合.
Maven还是Ant?这是一个非常类似的问题,它可以帮助你回答你的问题.
什么是Maven?在官方网站上.
编辑:对于一个新的/绿地项目,我建议使用Maven:"约定优于配置"将为您节省大量的时间来编写和设置构建和部署脚本.当您使用ant时,构建脚本的长度和复杂性会随着时间的推移而增长.对于现有项目,可能很难将其配置/布局塞进Maven系统.
只是列出一些更多的差异:
Ant没有正式的约定.你必须准确告诉Ant在哪里找到源,在哪里放置输出等.
Ant是程序性的.你必须告诉Ant究竟要做什么; 告诉它编译,复制,然后压缩等
Ant没有生命周期.
Maven使用约定.只要您遵循这些约定,它就会自动知道源代码的位置.你不需要告诉Maven它在哪里.
Maven是声明性的; 您所要做的就是创建一个pom.xml文件并将您的源代码放在默认目录中.Maven将负责其余的工作.
Maven有一个生命周期.您只需调用mvn install并执行一系列序列步骤.
Maven拥有关于常见项目任务的情报.要运行测试,只需执行mvn test,只要文件位于默认位置即可.在Ant中,你首先必须要JUnit JAR文件,然后创建一个包含JUnit JAR的类路径,然后告诉Ant它应该在哪里寻找测试源代码,编写一个编译测试源的目标然后最终执行单元测试与JUnit.
更新:
这来自Maven:The Definitive Guide.对不起,我完全忘了引用它.
Maven充当依赖管理工具 - 它可用于从中央存储库或您设置的存储库中检索jar,以及作为声明性构建工具."声明式"构建工具与更传统的构建工具(如ant或make)之间的区别在于您配置需要完成的工作,而不是如何完成.例如,您可以在maven脚本中说项目应该打包为WAR文件,maven知道如何处理它.
Maven依赖于有关项目目录如何布局的约定,以实现其"声明性".例如,它有一个约定,用于放置主代码的位置,放置web.xml的位置,单元测试等等,但如果需要,还可以更改它们.
您还应该记住,有一个插件可以在maven中运行ant命令:
http://maven.apache.org/plugins/maven-ant-plugin/
此外,maven的原型使得项目开始非常快.例如,有一个Wicket原型,它提供了一个maven命令,您可以运行该命令来获得一个完整的,可立即运行的hello world-type项目.
https://wicket.apache.org/start/quickstart.html
我可以带一个从未见过Ant的人 - 它build.xml
的写得非常好 - 他们可以理解发生了什么.我可以接受同一个人并向他们展示一个Maven POM,他们不会知道发生了什么.
在一个庞大的工程组织中,人们写到Ant文件变得庞大且难以管理.我编写了这些类型并清理了Ant脚本.它真正了解您需要做的事情,并设计一组模板,这些模板可以响应变化并在3年以上的时间内进行扩展.
除非你有一个简单的项目,否则学习Maven约定和Maven关于完成任务的方法是相当多的工作.
在一天结束时,您不能将Ant或Maven的项目启动视为一个因素:它实际上是总拥有成本.组织在几年内维护和扩展其构建系统所需的是必须考虑的主要因素之一.
构建系统最重要的方面是依赖管理和表达构建配方的灵活性.如果做得好,它必须有点直观.
我会说这取决于你的项目的大小......个人而言,我会将Maven用于需要直接编译,打包和部署的简单项目.一旦你需要做一些更复杂的事情(许多依赖,创建映射文件......),我会切换到Ant ...