蚂蚁和Maven之间的区别 [已关闭]
有人能告诉我蚂蚁和Maven之间的区别吗?我也从未使用过。我知道它们用于自动化Java项目的构建,但我不知道从哪里开始。
有人能告诉我蚂蚁和Maven之间的区别吗?我也从未使用过。我知道它们用于自动化Java项目的构建,但我不知道从哪里开始。
在《Maven: The Definitive Guide》一书中,我在引言中写了Maven和Ant之间的差异,章节标题是“Ant和Maven之间的差异”。这是一个答案,是该介绍中的信息与一些附加说明的组合。
简单比较
我向您展示这一点只是为了说明在最基本的层面上,Maven具有内置约定的想法。下面是一个简单的 Ant 构建文件:
<project name="my-project" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src/main/java"/>
<property name="build" location="target/classes"/>
<property name="dist" location="target"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file
-->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
在这个简单的 Ant 示例中,您可以看到如何确切地告诉 Ant 该做什么。有一个编译目标,其中包括javac任务,该任务将src/main/java目录中的源代码编译为target/classes目录。你必须告诉 Ant 你的源代码在哪里,你希望将生成的字节码存储在哪里,以及如何将所有这些打包到一个 JAR 文件中。虽然最近的一些发展有助于降低 Ant 的过程性,但开发人员使用 Ant 的经验是编写用 XML 编写的过程语言。
将前面的 Ant 示例与 Maven 示例进行对比。在 Maven 中,要从某个 Java 源代码创建 JAR 文件,您需要做的就是创建一个简单的 pom.xml,将源代码放在 ${basedir}/src/main/java 中,然后从命令行运行 mvn install。示例 Maven pom.xml,可获得相同的结果。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
这就是你所需要的一切.xml。从命令行运行 mvn install 将处理资源、编译源代码、执行单元测试、创建 JAR,并将 JAR 安装在本地存储库中以便在其他项目中重用。无需修改,您就可以运行 mvn 站点,然后在目标/站点中找到一个索引.html文件,其中包含指向 JavaDoc 的链接以及一些关于源代码的报告。
诚然,这是最简单的示例项目。仅包含源代码并生成 JAR 的项目。遵循 Maven 约定且不需要任何依赖项或自定义的项目。如果我们想开始自定义行为,我们的pom.xml将会越来越大,在最大的项目中,你可以看到非常复杂的Maven POM的集合,其中包含大量的插件自定义和依赖声明。但是,即使您的项目的POM文件变得更加重要,它们也包含与使用Ant的类似大小的项目的构建文件完全不同的信息。Maven POMs包含声明:“这是一个JAR项目”和“源代码在src / main / java中”。Ant 构建文件包含明确的说明:“这是项目”,“源代码在”,“针对此目录运行”,“将结果放入”,“从....”创建JAR等。Ant必须明确说明这个过程,Maven有一些“内置”的东西,只需要知道源代码在哪里以及应该如何处理它。src/main/java
javac
target/classses
高级比较
在这个例子中,蚂蚁和Maven之间的区别是什么?蚂蚁。。。
其中 Maven...
mvn install
常春藤呢?
是的,所以像史蒂夫·洛夫兰这样的人会读到这个比较并称之为犯规。他将讨论答案如何完全忽略了一种叫做Ivy的东西,以及Ant可以在最近的Ant版本中重用构建逻辑的事实。这是事实。如果你有一群聪明的人使用蚂蚁+蚂蚁+常春藤,你最终会得到一个设计精良的构建。尽管我非常相信Maven是有道理的,但我很乐意与一个拥有非常敏锐的构建工程师的项目团队一起使用Ant + Ivy。话虽如此,我确实认为你最终会错过许多有价值的插件,比如Jetty插件,你最终会做一大堆你不需要做的工作。
比Maven vs. Ant更重要
Maven 是一个框架,Ant 是一个工具箱
Maven是一辆预先建造的公路车,而Ant是一套汽车零件。使用Ant,您必须制造自己的汽车,但至少如果您需要进行任何越野驾驶,则可以制造出正确类型的汽车。
换句话说,Maven是一个框架,而Ant是一个工具箱。如果你满足于在框架的范围内工作,那么Maven会做得很好。对我来说,问题是我一直撞到框架的边界,它不会让我出去。
XML 详细程度
tobrien是一个对Maven了解很多的人,我认为他对这两种产品进行了非常好,诚实的比较。他将一个简单的 Maven pom.xml与一个简单的 Ant 构建文件进行了比较,并提到了 Maven 项目如何变得更加复杂。我认为值得一看的是,在一个简单的现实世界项目中,您更有可能看到几个文件的比较。下面的文件表示多模块版本中的单个模块。
首先,Maven 文件:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-4_0_0.xsd">
<parent>
<groupId>com.mycompany</groupId>
<artifactId>app-parent</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>persist</artifactId>
<name>Persistence Layer</name>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<scope>compile</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>domain</artifactId>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>${oracle-jdbc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${easymock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
和等效的 Ant 文件:
<project name="persist" >
<import file="../build/common-build.xml" />
<path id="compile.classpath.main">
<pathelement location="${common.jar}" />
<pathelement location="${domain.jar}" />
<pathelement location="${hibernate.jar}" />
<pathelement location="${commons-lang.jar}" />
<pathelement location="${spring.jar}" />
</path>
<path id="compile.classpath.test">
<pathelement location="${classes.dir.main}" />
<pathelement location="${testng.jar}" />
<pathelement location="${dbunit.jar}" />
<pathelement location="${easymock.jar}" />
<pathelement location="${commons-dbcp.jar}" />
<pathelement location="${oracle-jdbc.jar}" />
<path refid="compile.classpath.main" />
</path>
<path id="runtime.classpath.test">
<pathelement location="${classes.dir.test}" />
<path refid="compile.classpath.test" />
</path>
</project>
tobrien用他的例子来表明Maven有内置的约定,但这并不一定意味着你最终会写更少的XML。我发现事实恰恰相反。pom.xml比构建长3倍.xml这并没有偏离惯例。实际上,我的 Maven 示例没有显示配置插件所需的额外 54 行。那个pom.xml是一个简单的项目。当您开始添加额外的需求时,XML 确实开始显着增长,这对于许多项目来说并不罕见。
但你必须告诉蚂蚁该做什么
当然,我上面的蚂蚁例子并不完整。我们仍然需要定义用于清理,编译,测试等的目标。这些在由多模块项目中的所有模块导入的通用生成文件中定义。这让我想到了一点,所有这些东西都必须在Ant中明确地编写,而在Maven中它是声明性的。
没错,如果我不必明确地编写这些Ant目标,它将节省我的时间。但是需要多少时间呢?我现在使用的常见构建文件是我5年前编写的,从那时起只有轻微的改进。在我对Maven进行了2年的实验之后,我从壁橱里拿出旧的蚂蚁构建文件,把它掸去灰尘,然后让它重新开始工作。对我来说,在5年的时间里,必须明确告诉蚂蚁该做什么的成本加起来不到一周。
复杂性
我想提到的下一个主要区别是复杂性及其在现实世界中的影响。Maven的构建旨在减少负责创建和管理构建过程的开发人员的工作量。为了做到这一点,它必须很复杂。不幸的是,这种复杂性往往会否定他们的预期目标。
与蚂蚁相比,Maven项目的构建人员将花费更多的时间:
相比之下:
熟悉
另一个区别是熟悉度。新开发人员总是需要时间来跟上速度。在这方面,熟悉现有产品会有所帮助,Maven的支持者正确地声称这是Maven的一个好处。当然,Ant 的灵活性意味着您可以创建任何您喜欢的约定。所以我使用的约定是将源文件放在目录名称src/main/java中。我编译的类进入一个名为 target/classes 的目录。听起来很熟悉,不是吗。
我喜欢Maven使用的目录结构。我认为这是有道理的。还有它们的构建生命周期。因此,我在 Ant 构建中使用相同的约定。不仅仅是因为它有意义,而且因为以前使用过Maven的人都会熟悉它。