使用Gradle编译Java工程之自定义Task类型篇

文章目的

本章中我们将会学习到如何自定义任务(Task)的类型,了解Gradle是怎么增强任务的功能的。

需要准备

  • 一个熟悉的IDE开发工具
  • JDK 7及以上
  • Gradle 3.2以上

Gradle的两种任务类型

在上一章中(http://www.jianshu.com/p/a41769bf5118), 我们介绍了任务(Task)的一些高级用法,知道了Gradle对任务的功能增强很多,那么它是具体如何做到的呢?在揭晓答案之前,我们先来看看Gradle都支持哪两种类型的任务吧。
第一种为简单任务类型,就是我们在之前一篇文章中介绍的(http://www.jianshu.com/p/a7b947c86650), 它的行为是定义在一个动作闭包方法中的, 这种简单类型的任务适合在一个编译脚本中实现一种功能。而第二种为增强的任务类型,它的行为被提前构建在了任务里,只是提供一些配置属性让我们去设置,这种任务可以在不的地方或不同的编译脚本中被重复使用,它正是我们上一章中介绍的任务类型。

这种高级的增强的任务类型是通过定义一个任务类来实现的,在Gradle中我们也可以自定义自己的增强类型类,我们可以使用多种语言来实现,比如java、scala等。不过Gradle本身是使用Groovy语言实现的,所以我在这里选择使用Groovy语言来实现。

实现自定义的任务类型

首先有三种方式来编写我们的任务类

  1. 在我们构建项目的build.gradle脚本中直接编写,这种方式的好处是任务类自动被编译加载到我们的classpath中,我们不需要额外做任何的事情,但是它有很明显的局限性,就是除了在包括它的脚本外别的地方无法复用。

  2. 在我们构建项目的rootProjectDir/buildSrc/src/main/groovy 目录下编写,Gradle会自动编译到当前项目的classpath中,该项目下所有编译脚本都可以使用,但是除了当前项目之外的都无法复用。

  3. 以单独的工程方式编写,这个工程最终编译发布为一个JAR包,它可以在多个项目或不同的团队中共享使用。

然后我们先使用第一种方式编写一个简单的自定义任务类,而该自定义任务类是继承自DefaultTask的,同时为它添加一个行为方法,该方法需要使用TaskAction进行标注,这样Gradle就会在任务执行的时候默认调用它,其build.gradle中代码如下所示:

task hello(type: GreetingTask)

class GreetingTask extends DefaultTask {
    @TaskAction
    def greet() {
        println 'hello from GreetingTask'
    }
}

执行命令gradle -q hello结果如下:

> gradle -q hello
hello from GreetingTask

当然我们可以为我们自定义的任务类添加属性,并且在使用的时候设置该属性值,其build.gradle中代码如下:

// 使用默认的属性值
task hello(type: GreetingTask)

// 自定义设置的属性值
task greeting(type: GreetingTask) {
    greeting = 'greetings from GreetingTask'
}

class GreetingTask extends DefaultTask {
    String greeting = 'hello from GreetingTask'

    @TaskAction
    def greet() {
        println greeting
    }
}

执行命令gradle -q hello greeting结果如下:

> gradle -q hello greeting
hello from GreetingTask
greetings from GreetingTask

以单独工程方式实现自定义任务类

我们使用IDEA开发工具创建一个Groovy的工程,然后在它的build.gradle文件中使用Groovy plugin,并且添加相关的依赖,代码如下:

apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

接着创建一个Groovy类,其文件为src/main/groovy/org/gradle/GreetingTask.groovy,相关代码如下:

package org.gradle

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class GreetingTask extends DefaultTask {
    String greeting = 'hello from GreetingTask'

    @TaskAction
    def greet() {
        println greeting
    }
}

我们可以使用maven-publish插件先发布到本地,这样我们机器上的其他工程就能在指定目录下找到我们的任务类了,修改build.gradle中代码如下:

apply plugin: 'groovy'
apply plugin: 'maven-publish'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

publishing{
    publications {
        mavenJava(MavenPublication) {
            from components.java

            groupId 'org.gradle'
            artifactId 'customPlugin'
            version '1.0-SNAPSHOT'

        }
    }

    repositories{
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url "../repo"
        }
    }
}

在IDEA工具中直接运行publish任务,就能完成发布工作,并在工程的上一级目录下生成发布包,具体操作和结果如下图所示:

图一 运行publish发布工程
图二 生布后的本地仓库目录

最后在另外一个工程中使用该任务类
使用IDEA开发工具新创建一个Gradle工程,在该工程中将使用我们上面单独定义的任务类,首先我们需要使用buildscript { } 块来使类添加到编译脚本的classpath中,下面build.gradle中的代码展示了如果加载本地仓库的任务类:

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath group: 'org.gradle', name: 'customPlugin',
                  version: '1.0-SNAPSHOT'
    }
}

task greeting(type: org.gradle.GreetingTask) {
    greeting = 'another project working!'
}

执行命令gradle -q greeting的结果如下:

> gradle -q greeting
another project working!

小结

本章通过实现了一个自定义任务类,让我们了解到了Gradle是如何增强任务功能的,下一节中我将继续介绍如何实现自定义的插件,自定义任务类一般是与自定义插件一起使用的。如果感觉兴趣的同学请关注我,我和朋友的新书《分布式服务架构:原理、设计与实战》也正式登陆京东了,如果有需要的可以直购买,里面有很多平时的工作经验分享。

参加技术分享


《分布式服务架构:原理、设计与实战》
杨彪的简书博客
云时代架构公众号
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容