Gradle

2021年11月21日 阅读数:17
这篇文章主要向大家介绍Gradle,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。



Maven 实战(六)——Gradle,构建工具的将来?


Maven 面临的挑战

软件行业新旧交替的速度之快每每使人咂舌,不用多少时间,你就会发现曾经大红大紫的技术已经成为了昨日黄花,固然,Maven 也不会例外。虽然目前它基本上是 Java 构建的事实标准,但咱们也能看到新兴的工具在涌现,好比基于 Goovy 的​​Gradle​​,而去年​​Hibernate 宣布从 Maven 迁移至 Gradle​​这一事件更是吸引了很多眼球。在此以前,我也听到了很多对 Maven 的抱怨,包括 XML 的繁冗,不够灵活,学习曲线陡峭等等。那 Gradle 是否可以在继承 Maven 优势的基础上,克服这些缺点呢?带着这个疑问,我开始阅读 Gradle 的文档并尝试着将一个基于 Maven 的项目转成用 Gradle 构建,本文所要讲述大概就是这样的一个体验。须要注意的是,本文彻底是基于 Maven 的角度来看 Gradle 的,所以对于 Ant 用户来讲,视角确定会大有不一样。html

Gradle 初体验

Gradle 的安装很是方便,下载 ZIP 包,解压到本地目录,设置 GRADLE_HOME 环境变量并将 GRADLE_HOME/bin 加到 PATH 环境变量中,安装就完成了。用户能够运行gradle -v命令验证安装,这些初始的步骤和 Maven 没什么两样。Gradle 目前的版本是 1.0-milestone-1,根据​​其 Wiki 上的 Roadmap​​,在 1.0 正式版发布以前,还至少会有 3 个里程碑版本,而 1.0 的发布日期最快也不会早于 6 月份。而正是这样一个看起来彷佛还不怎么成熟的项目,却有着​​让不少成熟项目都汗颜的文档​​,其包括了安装指南、基本教程、以及一份近 300 页的全面用户指南。这对于用户来讲是很是友好的,同时也说明了 Gradle 的开发者对这个项目很是有信心,要知道编写并维护文档可不是件轻松的工做,对于 Gradle 这样将来仍可能发生很大变更的项目来讲尤其如此。java

相似于 Maven 的​​pom.xml​​文件,每一个 Gradle 项目都须要有一个对应的​​build.gradle​​文件,该文件定义一些任务(task)来完成构建工做,固然,每一个任务是可配置的,任务之间也能够依赖,用户亦能配置缺省任务,就像这样:spring

defaultTasks 'taskB'

task taskA << {
println "i'm task A"
}

task taskB << {
println "i'm task B, and I depend on " + taskA.name
}

taskB.dependsOn taskA


运行命令$ gradle -q以后(参数 q 让 Gradle 不要打印错误以外的日志),就能看到以下的预期输出:app

i'm task A
i'm task B, and I depend on taskA


这不是和 Ant 一模一样么?的确是这样,这种“任务”的概念与用法与 Ant 及其类似。Ant 任务是 Gradle 世界的第一公民,Gradle 对 Ant 作了很好的集成。除此以外,因为 Gradle 使用的 Grovvy 脚本较 XML 更为灵活,所以,即便我本身不是 Ant 用户,我也仍然以为 Ant 用户会喜欢上 Gradle。框架

依赖管理和集成 Maven 仓库

咱们知道依赖管理、仓库、约定优于配置等概念是 Maven 的核心内容,抛开其实现是否最优不谈,概念自己没什么问题,而且已经被普遍学习和接受。那 Gradle 实现了这些优秀概念了么?答案是确定的。maven

先看依赖管理,我有一个简单的项目依赖于一些第三方类库包括 SpringFramework、JUnit、Kaptcha 等等。原来的 Maven POM 配置大概是这样的(篇幅关系,省略了部分父 POM 配置):ide

<properties>
<kaptcha.version>2.3</kaptcha.version>
</properties>

<dependencies>
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>


而后我将其转换成 Gradle 脚本,结果是惊人的:工具

dependencies {
compile('org.springframework:spring-core:2.5.6')
compile('org.springframework:spring-beans:2.5.6')
compile('org.springframework:spring-context:2.5.6')
compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')
testCompile('junit:junit:4.7')
}


注意配置从原来的 28 行缩减至 7 行!这还不算我省略的一些父 POM 配置。依赖的 groupId、artifactId、 version,scope 甚至是 classfier,一点都很多。较之于 Maven 或者 Ant 的 XML 配置脚本,Gradle 使用的 Grovvy 脚本杀伤力太大了,爱漂亮之心,人皆有之,相比于七旬老妇松松垮垮的皱纹,你们确定都喜欢少女紧致的脸蛋,XML 就是那老妇的皱纹。布局

关于 Gradle 的依赖管理起初我有一点担忧,就是它是否有传递性依赖的机制呢?通过文档阅读和实际试验后,这个疑虑打消了,Gradle 可以解析现有的 Maven POM 或者 Ivy 的 XML 配置,从而获得传递性依赖的信息,而且引入到当前项目中,这实在是一个聪明的作法。在此基础上,它也支持排除传递性依赖或者干脆关闭传递性依赖,其中第二点是 Maven 所不具有的特性。学习

自动化依赖管理的基石是仓库,Maven 中央仓库已经成为了 Java 开发者不可或缺的资源,Gradle 既然有依赖管理,那必然也得用到仓库,这固然也包括了 Maven 中央仓库,就像这样:

repositories {
mavenLocal()
mavenCentral()
mavenRepo urls: "http://repository.sonatype.org/content/groups/forge/"
}


这段代码几乎不用解释,就是在 Gradle 中配置使用 Maven 本地仓库、中央仓库、以及自定义地址仓库。在我实际构建项目的时候,能看到终端打印的下载信息,下载后的文件被存储在 ​​USER_HOME/.gradle/cache/​​ 目录下供项目使用,这种实现的方法与 Maven 又是及其相似了,能够说 Gradle 不只最大限度的继承 Maven 的不少理念,仓库资源也是直接拿来用。

Gradle 项目使用 Maven 项目生成的资源已经不是个问题了,接着须要反过来考虑,Maven 用户是否可以使用 Gradle 生成的资源呢?或者更简单点问,Gradle 项目生成的构件是否能够发布到 Maven 仓库中供人使用呢?这一点很是重要,由于若是作不到这一点,你可能就会丢失大量的用户。幸运的是 Gradle 再次给出了使人满意的答案。使用 Gradle 的 Maven Plugin,用户就能够轻松地将项目构件上传到 Maven 仓库中:

apply plugin: 'maven'
...
uploadArchives {
repositories.mavenDeployer {
repository(url: "http://localhost:8088/nexus/content/repositories/snapshots/") {
authentication(userName: "admin", password: "admin123")
pom.groupId = "com.juvenxu"
pom.artifactId = "account-captcha"
}
}
}


在上传的过程当中,Gradle 可以基于​​build.gradle​​生成对应的 Maven POM 文件,用户能够自行配置 POM 信息,好比这里的 groupId 和 artifactId,而诸如依赖配置这样的内容,Gradle 是会自动帮你进行转换的。因为 Maven 项目之间依赖交互的直接途径就是仓库,而 Gradle 既可以使用 Maven 仓库,也能以 Maven 的格式将本身的内容发布到仓库中,所以从技术角度来讲,即便在一个基于 Maven 的大环境中,局部使用 Gradle 也几乎不会是一个问题。

约定优于配置

如同 Ant 通常,Gradle 给了用户足够的自由去定义本身的任务,不过同时 Gradle 也提供了相似 Maven 的约定因为配置方式,这是经过 Gradle 的 Java Plugin 实现的,从文档上看,Gradle 是推荐这种方式的。Java Plugin 定义了与 Maven 彻底一致的项目布局:

  • src/main/java
  • src/main/resources
  • src/test/java
  • src/test/resources

区别在于,使用 Groovy 自定义项目布局更加的方便:

sourceSets {
main {
java {
srcDir 'src/java'
}
resources {
srcDir 'src/resources'
}
}
}


Gradle Java Plugin 也定义了构建生命周期,包括编译主代码、处理资源、编译测试代码、执行测试、上传归档等等任务:

Gradle_maven

Figure 1. Gradle 的构建生命周期

相对于 Maven 彻底线性的生命周期,Gradle 的构建生命周期略微复杂,不过也更为灵活,例如 jar 这个任务是用来打包的,它不像 Maven 那样依赖于执行测试的 test 任务,相似的,从图中能够看到,一个最终的 build 任务也没有依赖于 uploadArchives 任务。这个生命周期并无将用户限制得很死,举个例子,我但愿每次 build 都发布 SNAPSHOT 版本到 Maven 仓库中,并且我只想使用最简单的$ gradle clean build命令,那只须要添加一行任务依赖配置便可:

build.dependsOn 'uploadArchives'


因为 Gradle 彻底是基于灵活的任务模型,所以不少事情包括覆盖现有任务,跳过任务都很是易于实现。而这些事情,在 Maven 的世界中,实现起来就比较的麻烦,或者说 Maven 压根就不但愿用户这么作。

小结

一番体验下来,Gradle 给我最大的感受是两点。其一是简洁,基于 Groovy 的紧凑脚本实在让人爱不释手,在表述意图方面也没有什么不清晰的地方。其二是灵活,各类在 Maven 中难如下手的事情,在 Gradle 就是小菜一碟,好比修改现有的构建生命周期,几行配置就完成了,一样的事情,在 Maven 中你必须编写一个插件,那对于一个刚入门的用户来讲,没个一两天几乎是不可能完成的任务。

不过即便如此,Gradle 在将来可否取代 Maven,在我看来也仍是个未知数。它的一大障碍就是 Grovvy,几乎全部 Java 开发者都熟悉 XML,可又有几我的了解 Groovy 呢?学习成本这道坎是很难跨越的,不少人抵制 Maven 就是由于学起来不容易,你如今让由于一个构建工具学习一门新语言(即便这门语言和 Java 很是接近),那获得冷淡的回复几乎是必然的事情。Gradle 的另一个问题就是它太灵活了,虽然它支持约定优于配置,不过从本文你也看到了,破坏约定是多么容易的事情。人都喜欢自由,爱自定义,以为本身的需求是多么的特别,可事实上,从 Maven 的流行来看,几乎 95% 以上的状况你不须要自行扩展,若是你这么作了,只会让构建变得难以理解。从这个角度来看,自由是把双刃剑,Gradle 给了你足够的自由,约定优于配置只是它的一个选项而已,这初看起来很诱人,却也可能使其重蹈 Ant 的覆辙。Maven 在 Ant 的基础上引入了依赖管理、仓库以及约定优于配置等概念,是一个很大的进步,不过在我如今看来,Gradle 并无引入新的概念,给我感受它是一个结合 Ant 和 Maven 理念的优秀实现。

若是你了解 Groovy,也理解 Maven 的约定优于配置,那试试 Gradle 倒也不错,尤为是它几乎能和现有的 Maven 系统无缝集成,并且你也能享受到简洁带来的极大乐趣。其实说到简洁,也许在不久的未来 Maven 用户也能直接享受到,​​Polyglot Maven​​在这方面已经作了很多工做。本文彻底基于 Maven 的视角介绍 Gradle 这一构建工具的新秀,不过限于篇幅缘由,没法深刻 Gradle 的方方面面,例如 Gradle 也支持多模块构建,它提供了 GUI 操做界面,支持 Grovvy(理所固然)和 Scala 项目等等。有兴趣的读者能够自行进一步了解。

关于做者

许晓斌(Juven Xu),国内社区公认的 Maven 技术专家、Maven 中文用户组创始人、Maven 技术的先驱和积极推进者,著有​​《Maven 实战》​​一书。对 Maven 有深入的认识,实战经验丰富,不只撰写了大量关于 Maven 的技术文章,并且还翻译了开源书籍《Maven 权威指南》,对 Maven 技术在国内的普及和发展作出了很大的贡献。就任于 Maven 之父的公司,负责维护 Maven 中央仓库,是 Maven 仓库管理器 Nexus(著名开源软件)的核心开发者之一,曾屡次受邀到淘宝等大型企业开展 Maven 方面的培训。此外,他仍是开源技术的积极倡导者和推进者,擅长 Java 开发和敏捷开发实践。他的我的网站是:​


Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各类繁琐配置。


面向Java应用为主。当前其支持的语言限于Java、Groovy、Kotlin和Scala,计划将来将支持更多的语言。


 




简介

编辑

Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,支持maven, Ivy仓库,支持传递性依赖管理,而不须要远程仓库或者是pom.xml和ivy.xml配置文件,基于Groovy,build脚本使用Groovy编写。 [1] 





平常运用

编辑

功能


Ø gradle对多工程的构建支持很出色,工程依赖是gradle的第一公民。


Ø gradle支持局部构建。

  Ø 支持多方式依赖管理:包括从​​maven​​远程仓库、​​nexus​​私服、ivy仓库以及本地文件系统的jars或者dirs


Ø gradle是第一个构建集成工具,与ant、maven、ivy有良好的相容相关性。


Ø 轻松迁移:gradle适用于任何结构的工程,你能够在同一个开发平台平行构建原工程和gradle工程。一般要求写相关测试,以保证开发的插件的类似性,这种迁移能够减小破坏性,尽量的可靠。这也是重构的最佳实践。


Ø gradle的总体设计是以做为一种语言为导向的,而非成为一个严格死板的框架。


Ø 免费开源


  


gradle提供了什么


1.一种可切换的,像maven同样的基于约定的构建框架,却又从不锁住你(约定优于配置)


2. 强大的支持多工程的构建


3. 强大的依赖管理(基于Apache Ivy),提供最大的便利去构建你的工程


4. 全力支持已有的Maven或者Ivy仓库基础建设


5. 支持传递性依赖管理,在不须要远程仓库和pom.xml和ivy配置文件的前提下


6 基于groovy脚本构建,其build脚本使用​​groovy​​语言编写


7 具备普遍的领域模型支持你的构建