zoukankan      html  css  js  c++  java
  • Java Gradle入门指南之内建与定制任务类(buildSrc、Groovy等)

    博客逐步迁移至 极客兔兔的小站

        上一篇随笔介绍了Gradle的安装与任务管理,这篇着重介绍Gradle的内建任务(in-built tasks)与自定义任务(custom tasks),借助Gradle提供的众多内建任务类型以及自己定制的任务类型,Java Web、Android等的开发、测试、部署将会变得非常容易。这篇随笔提供的都是非常简单的示例,但这对于读懂Gradle脚本(例如常见的build.gradle)或者是书写Gradle脚本相信是有帮助的。本文所有代码测试环境为Gradle 2.11

        如有错误,请不吝指出,非常感谢;如本文对您有帮助,右下角点个推荐吧~

    1.内建任务类(in-built tasks)

        Gradle在不断地更新,其内建任务也在不断地丰富,这一章节介绍Gradle中最常用的几个内建任务类,这只是Gradle众多内建任务类中的一部分,抛砖引玉,更多方法可以参见Gradle官方文档

    1.1 复制(Copy)

        项目开发和部署过程中,复制文件是很常见的工作,gradle为了简化开发步骤提供了大量的内建任务类,Copy便是其中之一

    • 先看一段最简单的代码
    // org.gradle.api.tasks.Copy
    // 将in.txt从当前文件夹复制到abc文件夹(不存在则新建)
    // 代码中的路径为相对路径
    task copyTask(type: Copy) {
        from '.'
        into 'abc'
        include 'in.txt'
    }
    
    • includeexclude

    (1) include '*' => 包含所有的文件以及文件夹

    (2) include/exclude '*.xml' => 包含/排除当前文件夹下xml类型文件

    (3) include/exclude '*.txt','*.data' =>包含/排除多类文件,逗号隔开
    (4) include/exclude '**/*.xml' => 包含/排除所有文件夹下xml类型文件

    • with
    // 定义一个copySpec,通常是重复使用的语句
    // 插入到Task中
    def dataContent = copySpec {
       from 'src'
       include '*.data'
    }
    
    task copyTask(type: Copy) {
        from('.') {
            exclude '*.txt', '*.xml' //排除txt、xml类型的文件 
        }
        into 'build'
        include '*'
        
        includeEmptyDirs = false
        with dataContent  
    }
    
    • 其他属性

    (1) caseSensitive => 大小写敏感,true/false,默认为true

    (2) includeEmptyDirs => 是否包含空文件夹,true/false,默认为true

    (3) filter => 重用org.apache.tools.ant.filters.*的方法

    (4) 更多参见官方文档

    1.2 重命名(Rename)

    • 闭包方法
    // rename(Closure closure)
    // 执行gradle cT
    // 将当前文件夹下的所有.txt文件复制到build/中,并将后缀改为.data
    task copyTask(type: Copy) {
        from '.'
        into 'build'
        include '*.txt'
        rename { String fileName ->
            fileName.replace('.txt' , '.data')
        }
    }
    
    • 正则表达式
    // rename(String sourceRegEx, String replaceWith)
    // 将所有以out开头的文件复制到build/,并将out替换为output
    // $指代正则表达式匹配的地方,从1开始
    task copyTask(type: Copy) {
        from '.'
        into 'build'
        include '*.txt'
        rename 'out(.*)', 'output$1' //=> out.txt->output.txt
        // rename '(.*)t(.*)', '$1output$2'
    } 
    
    >> 原来的结构如下
    --Test/
       |--out.txt
       |--build.gradle
    >> 执行任务后结构
    --Test/
       |--build/
          |--output.txt
       |--out.txt
       |--build.gradle
    

    1.3 打包(Zip)

    // 执行gradle zT 
    // 将src文件夹下所有文件打包到dest/文件夹下
    task zipTask(type: Zip) {
        File destDir = file('dest')
        archiveName 'abc.zip'
        from 'src'
        destinationDir destDir
    }
    
    >> 原来的结构如下
    --Test/
       |--src/
          |--hello.java
          |--world.java
       |--build.gradle
    >> 执行任务后结构
    --Test/
       |--dest/
          |--abc.zip  // 解压后为hello.java和world.java2个文件
       |--src/
          |--hello.java
          |--world.java
       |--build.gradle
    

    1.4 删除(delete)

        项目打包时,往往需要删除调试、测试时的临时文件,例如输出、日志等,可以使用内建方法Delete完成这个任务,使用也非常简单

    task deleteTask(type: Delete) {
        delete 'out.txt','log.txt'
    }
    

    1.5 执行(Exec)

        每次执行时,都要切换环境,敲入命令,gradle提供了Exec内建方法去简化调试、测试过程,可以根据需要编写代码

    // Java Web开发,关闭Tomcat
    task stopTomcat(type:Exec) {
        workingDir '../tomcat/bin'
        //linux下
        commandLine './stop.sh'
        // 重定向输出到扩展属性output,而不是控制台
        // 当然可以改为输出到文件
        standardOutput = new ByteArrayOutputStream()
        ext.output = {
            return standardOutput.toString()
        }
    }
    
    • 其他属性

    (1) args(args) =>命令参数,List <String>

    (2) commandLine(args) =>命令,List <String>

    (3) environment(name, value),=> 临时添加一个环境变量,多个需Map

    (4) workingDir(dir) => 工作目录,file类型

    (5) 更多参见官方文档

    2.定制任务(custom tasks)

        Gradle支持大量的插件,例如war、java、gretty等,这些插件能够自动化自动化编译、打包等过程,但是有时由于项目需求,插件并不能满足项目的需求,Gradle支持定制任务类去完成你的工作。接下来将介绍三种定制Gradle任务类的方法

    2.1 创建build文件

    // .../Test/build.gradle
    println 'I Am A Custom Task'
    
    class HelloTask extends DefaultTask {
        String nickName = 'default'
    
        @TaskAction
        def action1() { println 'Step 3 I Am ' + name }
    
        @TaskAction
        def action2() { println 'Step 2 NickName Is ' + nickName }
    }
    
    task hello(type: HelloTask) {
        nickName = 'gzdaijie'
        doFirst { println 'Step 1' }
        doLast { println 'Step 4' }
    }
    
    执行结果
    C:UsersgzdDesktopTest>gradle -q hello
    I Am A Custom Task
    Step 1
    Step 2 NickName Is gzdaijie
    Step 3 I Am hello
    Step 4
    
    • name是内置属性,值为任务名称,doFirst,doLast内置方法
    • 扩展自类DefaultTask@TaskAction新增Action
    • 关于Task基础知识的介绍,可以参考我的上一篇博客

    2.2 创建buildSrc目录

        事实上,build.gradle文件中不适合写类的定义,假设我们定制的每个Task类都写在build.gradle中,那么build.gradle文件将会变得很大,可读性大大降低,但是又不想为此单独创建一个工程,那么将代码写在buildSrc文件夹中将是一个很好的选择。

    // 文件 HelloTask.groovy
    import org.gradle.api.DefaultTask
    import org.gradle.api.tasks.TaskAction
    
    class HelloTask extends DefaultTask {
        String nickName = 'default'
    
        @TaskAction
        def action1() { println 'Step 3 I Am ' + name }
    
        @TaskAction
        def action2() { println 'Step 2 NickName Is ' + nickName }
    }
    
    // 文件 build.gradle
    task hello(type: HelloTask) {
        nickName = 'gzdaijie'
        doFirst { println 'Step 1' }
        doLast { println 'Step 4' }
    }
    
    新建文件 buildSrc/src/main/groovy/ch3/HelloTask.groovy
    目录结构如下
    ---Test/
      |--build.gradle
      |--buildSrc/
         |--src/
            |--main/
               |--groovy/
                  |--ch3/
                     |--HelloTask.groovy
    执行gradle -q hello
    结果与2.1一致,build.gradle中的代码显得十分干净
    

    2.3 创建独立的groovy项目

        新建一个groovy项目,命名为HelloTask,可以使用eclipse、IDEA等IDE,接下来纯手工建项目吧~

    • 新建文件~/HelloTask/src/main/groovy/HelloTask.groovy,将之前的HelloTask复制进去,然后在HelloTask/目录下新建文件build.gradle,这里我们同样使用gradle来构建groovy项目。
    // => HelloTask/build.gradle
    // apply plugin 应用插件
    apply plugin: 'groovy'
    version=1.0
    dependencies {
        // 添加依赖
        compile gradleApi()
        compile localGroovy()
    }
    
    
    目录结构如下
    --HomeDir
      |--Test
         |--build.gradle
      |--HelloTask
         |--build.gradle
         |--src
            |--main
               |--groovy
                  |--HelloTask.groovy
    在HelloTask/ 下执行gradle build
    你会发现该目录下多了build/libs/HelloTask-1.0.jar
    这就是我们编译好的定制任务类
    
    • 接下来在HelloTask/ 下执行 gradle build,gradle会在src/main/groovy目录下搜寻所有的类build
    • 回到Test/目录,清空所有内容,只留下build.gradle,写入以下内容
    // => Test/build.gradle
    // buildscript 配置导入路径,包信息
    buildscript {
        repositories {
            flatDir {  dirs '../HelloTask/build/libs' }
        }
        dependencies {  classpath group: 'ch3', name:'HelloTask',version:'1.0'  }
    }
    
    task hello(type: HelloTask) {
        nickName = 'gzdaijie'
        doFirst { println 'Step 1' }
        doLast { println 'Step 4' }
    }
    
    • 在Test/ 中执行gradle hello,效果和2.1、2.2完全一致

    3.小结

        1中介绍了常用的内建Task类,2.3中使用了Gradle创建了Groovy项目,并用了buildscript导入了编译好的包,入门指南写到这里,build.gradle已经很接近使用IDE(例如Eclipse、IDEA、Andriod Studio)自动生成的build.gradle文件了,Gradle依赖管理的威力已经开始显现。
        实际项目开发中,更多地是导入maven仓库,而不是自己写依赖,但是希望这个指南能给希望了解Gradle的博友带来帮助,喜欢就关注一下吧~

  • 相关阅读:
    安装最新版Mysql(APT方式安装)
    Tengine环境安装
    Docker 教程
    Docker Redis
    Ubuntu
    spring boot actuator 如何显示详细信息
    spring boot 加载日志框架后经常出现 LOG_PATH_IS_UNDEFINED 目录怎么办?【未解决】
    Tomcat 目录结构以及基本配置
    Java Hash集合的equals()与hashCode() 方法
    Java Map 集合实现类
  • 原文地址:https://www.cnblogs.com/gzdaijie/p/5285160.html
Copyright © 2011-2022 走看看