Java构建工具:Maven与Gradle的对比
Posted 天码营
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java构建工具:Maven与Gradle的对比相关的知识,希望对你有一定的参考价值。
「内容简介」Maven在如今仍然是Java构建技术的事实标准,但是从Gradle身上,我们确实看到了进步。简洁的Groovy语法和灵活的配置令我们眼前一亮。那Maven和Gradle到底有何不同呢?今天和我一起来了解吧。
在Java码农的世界里,构建工具一直是一个不可或缺的元素。一开始,世上是只有一个构建工具的那就是Make
后来发展为GNU Make
。但是由于需求的不断涌现,这个小圈子里又逐渐衍生出其他千奇百怪的构建工具。
在这个小圈子中影响力最大的角色莫过于Maven
了。它使用XML
作为配置文件,改进了前辈Ant
的复杂的构建配置,提供了一些现成的目标,而不需要我们一个个的将构建任务的每个命令一一列出。另外它提供了一个杀手锏功能,那就是依赖管理
,它通过简单的配置就可以自动从网络上下载项目所需的依赖,这革命性的改变了我们开发软件的方式。可以想象,如果你是一个大型软件开发项目组的成员,如果使用代码仓库管理依赖jar包会令仓库变得多么庞大!Maven的制品仓库设计实现了制品与代码间的解耦,为基于制品的协作提供了可能。
可是软件行业新旧交替的速度之快往往令人咋舌,不用多少时间,你就会发现曾经大红大紫的技术已经成了昨日黄花。在Java构建领域,我们能够看到一些新兴的工具在涌现。比如基于Groovy
的Gradle
。Hibernate
就将自己的项目从Maven迁移到了Gradle,Google官方android开发的IDE Android Studio
也默认使用了Gradle进行构建。这些事件令Gradle吸引了不少眼球。Gradle真的要替代Maven了么?当然没有,Maven在如今仍然是Java构建技术的事实标准。Gradle也仍然使用了Maven的制品库来做依赖管理。但是从Gradle身上,我们确实看到了进步。简洁的Groovy语法和灵活的配置令我们眼前一亮。
那Maven和Gradle到底有何不同呢?就请读者和我一起探寻吧。
安装
在安装上两者大同小易。我们都需要从官网下载解压到本地目录。配置好MAVEN_HOME
或Gradle_Home
环境变量,并加入PATH
环境变量中。我们就可以在命令行中使用maven和gradle了。
主流的Java IDE: Eclipse可以安装Maven和Gradle的插件。Intellij有内置的Gradle和Maven可以使用。
二者均有详尽的文档供用户参考。别看gradle是个新来的小子,它的文档也是有70章,500多页的内容的!
maven:
gradle:
依赖管理
Maven的配置文件是.pom
文件。POM是项目对象模型(Project Object Model)的简称,它是Maven项目中的文件,使用XML表示。其中包含项目的基本信息,构建过程,环境信息,依赖信息等。我们可以看下面这个简单的例子:
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vs</groupId> <artifactId>com.vs.maven.gradle</artifactId> <version>1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa </artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
这个例子构建了一个简单的spring-boot项目, 最开始定义了一些项目的基本信息,包括组名、制品名、版本等。parent
标签表示我们继承了一个spring定义的一个制品的配置,这样我们不需要配置很多依赖的版本就可以引入依赖。dependencies
标签间配置该项目所依赖的其他制品,分别配置每个依赖制品的groupId, artifactId和version。当我们执行mvn insall
时,maven就会自动下载依赖,并帮我们将它编译打包放入本地仓库之中。我们就可以在用户目录下的.m2
文件夹中找到我们的制品。
那如果我们使用Gradle来构建这个项目,我们该如何做呢?
buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE") } } dependencies { compile("org.springframework.boot:spring-boot-starter-web") { exclude module: "spring-boot-starter-tomcat" } compile("org.springframework.boot:spring-boot-starter-security") compile("org.springframework.boot:spring-boot-starter-data-jpa") testCompile("mysql:mysql-connector-java:5.1.25") }
咦?冗长的代码怎么突然少了这么多?^?
仔细阅读下你会发现,原来是依赖管理所需的配置长度变短了。在pom.xml中我们需要引入一个依赖时需要将它的groupId, artifactId和version都用标签引起来。但是在build.gradle中你会发现,仅仅需要将三者的value用:连起来,并"调用compile函数"就可以啦。
比如,我们要引用spring-boot的starter-security,maven的配置是这样写的:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies>
在gradle中的配置却是这样的:
dependencies { compile("org.springframework.boot:spring-boot-starter-security") }
觉得怎么样?我反正感觉和写代码一样清爽!Gradle使用了groovy作为它的DSL,非常的易用。如果你使用了很久的Maven,你也许会发现Gradle的配置写起来实在是太爽了!
构建生命周期管理
除了依赖管理以外,构建工具的另一个主要用途就是构建的生命周期管理。
Maven有三个生命周期,每个生命周期又分为多个阶段:
Clean:包含3个阶段,与清理上次构建生成的文件相关
Default:Maven的核心生命周期,包含多个阶段如预处理、编译、测试、打包、安装到本地仓库、发布到远程仓库等。
Site: 包含4个阶段,与生成项目报告,站点,发布站点相关。
这些生命周期都是系统自定义好的,如果我们需要修改现有的构建生命周期的话,我们就要编写一个Maven插件。因为Maven是通过插件发来完成大多数的构建任务。每个插件可以绑定一个生命周期。配置好绑定生命周期后,我们需要定义插件的任务,在Maven中每个任务的goal称作Mojo,每个Mojo我们都需要实现org.apache.maven.plugin.Mojo
接口。也就是我们需要定义一个类来实现这个接口。使用时我们需要引入这个插件,并配置需要执行的goal。
比如我们要完成输出Hello world
这个需求的话,我们需要:
新建GreeingMojo类:
package sample.plugin; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; /** * Says "Hi" to the user. * */ @Mojo( name = "sayhi") public class GreetingMojo extends AbstractMojo { public void execute() throws MojoExecutionException { getLog().info( "Hello, world." ); } }
定义pom文件:
<project> <modelVersion>4.0.0</modelVersion> <groupId>sample.plugin</groupId> <artifactId>hello-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <packaging>maven-plugin</packaging> <name>Sample Parameter-less Maven Plugin</name> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>2.0</version> </dependency> <!-- dependencies to annotations --> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.4</version> <scope>provided</scope> </dependency> </dependencies> </project>
在项目pom文件目录运行install命令将插件安装到本地仓库
在使用插件的项目加入配置:
<build> <plugins> <plugin> <groupId>sample.plugin</groupId> <artifactId>hello-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> </plugin> </plugins> </build>
执行:
mvn groupId:artifactId:version:goal
即可完成Hello,world的输出。
那么在Gradle中我们该怎么做呢?Gradle中有一个基本概念叫Task
,我们可以使用Task
来完成这个需求:
task hello << { println "hello world" }
执行Gradle hello
,即可完成Hello, World的输出。是不是很简单?像写代码一样~
当然实际工程我们要完成的构建任务不仅仅是输出一个info这么简单,我们很可能会去做一些其他复杂的操作,比如初始化文件、数据库,检测系统环境等等。但由于Gradle使用了Groovy作为配置文件,在使用时会比Maven的xml配置灵活许多,更适合我们码农进行使用。
制品发布
在制品发布这个操作上,Maven要扳回一局。Maven原生支持maven jar的格式,发布很简单;而Gradle虽说既支持Maven又支持Gradle,但是就要我们自己做很多额外的工作。比如Maven要发布制品,只需要配置远程仓库的参数:
<distributionManagement> <repository> <id>internal</id> <name>Internal Release Repository</name> <url>http://repository.springsource.com/maven/bundles/release</url> </repository> </distributionManagement>
而gradle发布制品,还需要生成pom文件:
uploadArchives { repositories { mavenDeployer { //为Pom文件做数字签名 beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "http://repository.springsource.com/maven/bundles/release") { authentication(userName: username, password: password) } //构造项目的Pom文件 pom.project { name project.name packaging 'jar' description 'description' } } } }
总结
因为时间关系,简单介绍了这么多,可能读者也对Gradle与Maven的差别有了一些了解。Gradle与Maven相比更为灵活,简单。但是Maven相比于Gradle的不灵活,是否也是它的优点呢?这就需要读者在工程中自己进行思考了。
除此之外Gradle的官方网站专门给出了一个专栏来讲Gradle与Maven的区别: 。
有耐心的读者可以看看这些对比。如果说你要说我没耐心看完这些,只想快点挑个构建工作开始我的项目! 那么我要说的是:Just have a try! Maven和Gradle都是非常优秀的构建工具,增加二者的使用经验不是一个很亏的事情。当然如果你要开发Android应用的话,还是推荐你使用Gradle做构建工具,因为Google官方推的Android Studio就使用了Gradle作为原生构建工具,这使得Gradle对Android各版本软件的构建支持得更好一些。其他项目的话,二者选其一吧~
了解更多Java Web开发内容:
点击下方“阅读原文”,可以获得更多天码营教程。
以上是关于Java构建工具:Maven与Gradle的对比的主要内容,如果未能解决你的问题,请参考以下文章