离线下载
PDF版 ePub版

Lippi · 更新于 2017-09-22 10:00:28

Gradle 起步

Gradle目前的版本是2.4,根据其Wiki上的Roadmap,Gradle有着让很多成熟项目都汗颜的文档,其包括了安装指南、基本教程、以及一份近300页的全面用户指南。这对于用户来说是非常友好的,同时也说明了Gradle的开发者对这个项目非常有信心,要知道编写并维护文档可不是件轻松的工作,对于Gradle这样未来仍可能发生很大变动的项目来说尤为如此。

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

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不要打印错误之外的日志),就能看到如下的预期输出:

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实现了这些优秀概念了么?答案是肯定的。

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

    <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也几乎不会是一个问题。 ## 约定优于配置

上一篇: 安装Gradle 下一篇: 使用命令行