Java Gradle入門指南之簡介、安裝與任務管理

博客逐步遷移至 極客兔兔的小站java

    這是一篇Java Gradle入門級的隨筆,主要介紹Gradle的安裝與基本語法,這些內容是理解和建立build.gradle的基礎,關於Gradle各類插件的使用將會在其餘隨筆中介紹。
    有什麼疑問歡迎在文末關注留言,若是本文對你有用,那在右下角點個推薦吧~api

1.Gradle簡介與安裝

1.1 簡介

  • Gradle是一個基於Apache Ant和Apache Maven概念的項目自動化建構工具。它使用一種基於Groovy的特定領域語言(DSL)來聲明項目設置,拋棄了基於XML的各類繁瑣配置。面向Java應用爲主。
  • Gradle支持多工程構建,提供強大的依賴管理,支持傳遞性依賴管理(無需配置XML);自動化Java開發中的編譯、打包、執行測試案例等過程;同時Gradle支持豐富的插件,例如Java Web自動化部署的war、gretty插件等。

1.2 安裝

  • Windows:下載安裝包,安裝以後,將GRADLE_HOME/bin添加到環境變量。
  • Linux:安裝Gradle以後,配置PATH工具

    (1) 在~/.profile中加入GRADLE_HOME = YOUR_INSTALLATION_DIR
    (2) 在~/.profile中加入PATH=$PATH:$GRADLE_HOME/bin

    (3) 執行source ~/.profile從新加載profile文件測試

  • 命令行下執行gradle -v可測試配置是否正確,更多命令行用法可執行gradle -h
  • 本文代碼測試版本爲Gradle 2.11gradle

2.任務(task)管理

    一個腳本是一系列待執行操做(action)、屬性的集合,有時,咱們只想執行其中的某幾個操做,那這幾個操做及其相關的屬性構成了一個任務(task),任務是gradle中的執行單元。比任務更大的是項目(project),每每包括多個任務。優化

2.1 建立第一個task

task hello << {
    println "Hello World!" + project.name // => Test
    // 或 println "Hello World!$project.name" // =>Test
}
  • 在某個目錄下(例如~/Test)新建文件build.gradle,文件內寫入上述代碼
  • 切換到該目錄,執行gradle hello,執行結果爲Hello World!Test,若沒有單獨配置,項目名通常與當前文件夾名稱相同。
  • 執行這個腳本時,gradle調用org.gradle.api.Project建立一個實例project ,你能夠用project.XX(在字符串中用$project.XX)去使用這個實例
  • project有四個屬性,name(只讀),parent(只讀),version,description

2.2 設置屬性與任務執行

//已存在屬性直接賦值便可
version = "1.0"  
description = "I Am A Gradle Test!"  
// 新增屬性須要使用 ext
ext {
    createDate = "Mar 2016"  
}
ext.creator = "呆尐兔兔"
// task hello1
task hello1 {
    doFirst {
        // name爲task的內置屬性,值爲task名稱
        println "1. My Name is " + name  // ==> hello
        println "2. I Belong To Project $project.name" //=>Test
    }
    doLast {
        println "3. The Version Is " + project.version
        println "4. I Am Created On " + project.createDate
    }
}
// task hello2
task hello2 << {
    ext { nickname = "excited"}
    println "Step 2: $nickname" //=> excited
}
hello2.doFirst { println "Step 1" }
hello2.doLast { println "Step 3 " }
執行結果以下
C:\Users\gzd\Desktop\Test>gradle hello1 hello2
:hello1
1. My Name is hello1
2. I Belong To Project Test
3. The Version Is 1.0
4. I Am Created On Mar 2016
:hello2
Step 1
Step 2: excited
Step 3
  • gradle [task1] [task2] [...],執行多個任務
  • hello是Task對象一個實例,一樣繼承了一些屬性,例如name、description等,可在task中使用ext新增屬性
  • doFirstdoLast方法爲task內置方法,前後執行, << 操做符在Groovy中做用是添加元素,三者一塊兒使用,順序doFirst-><<->doLast。<< 經常使用來開速添加任務。

2.3 任務依賴

// 單任務依賴
// 該任務依賴的其餘任務將先執行
task hello1 << {
    println "Step 1"
}
task hello2(dependsOn:hello1) << {
    println "Step 2"
}
// 等價於 task hello2 << { println "Step 2" }
// hello2.dependsOn hello1
// 多任務依賴
task hello2 << { 
    // ...
}
hello2.dependsOn hello1, hello3
// 等價於 task hello2(dependsOn: [hello1,hello3]) << { ... }

2.4 任務執行順序與動態任務

task hello1 << {
    println "Step 1"
}
task hello0 << {
    println "Step 0"
}
task hello2(dependsOn:[hello1,hello0]) << { 
    println "Step 2" 
}
task hello3 << {
    println "Step 3"
}
如下是執行結果
C:\Users\gzd\Desktop\Test>gradle hello2 hello3
Step 0
Step 1
Step 2
Step 3
  • 上述代碼存在任務1,2,3,4,任務2依賴於任務1與任務0,執行gradle hello2 hello3,將依次執行任務0,1,2,最後執行3。
  • 儘管任務1定義在任務0前面,依賴時順序也是 1,0,對於依賴的任務,gradle的執行順序按照字母表
  • gradle 提供了shouldRunAftermustRunAfterfinalizedBy三個選項幫助定義任務執行順序。
// 使用groovy語法動態構建任務
(1..6).each {
    task "hello$it" << {
        println "Executing $name" //=>hello(1..6) 見2.2
    }
}

hello1.dependsOn hello2
hello3.dependsOn hello2

hello5.finalizedBy hello6
hello5.mustRunAfter hello4
依次執行下列命令
gradle hello1 ==> 2->1
gradle hello1,hello3 ==> 2->1->3
gradle hello5 ==> 5->6
gradle hello5,hello4 ==> 4->5->6
  • shouldRunAfter表示應該但不強制,mustRunAfter表示強制
// 考慮如下代碼,執行gradle hello1將會報錯
// 換爲shouldRunAfter則不會報錯,執行順序爲3->2->1
hello1.dependsOn hello2
hello2.dependsOn hello3
hello3.mustRunAfter hello1
  • 另外一個例子
// 如下代碼將構建出hello0,hello1,hello2,hello3
// 下標從0開始
4.times { counter ->
    task "hello$counter" << {
        println "I'm $name" //=> hello[0..3]
    }
}
  • 使用addRule動態建立任務
// 如下代碼將匹配以clean開頭的任務
// 例如gradle cleanTest => Task is cleanTest
// gradle cleanHello => Task is cleanHello
tasks.addRule("Pattern:clean<fileName>") { String taskName ->
    if(taskName.startsWith("clean")) {
        task(taskName) << {
            println "Task is $name";
        }
    }
}

2.5 任務名稱簡寫

  • gradle支持在執行命令時使用任務的簡寫(每一個單詞第一個字母
  • 例如執行gradle hello1, 能夠簡寫爲gradle h1
  • 例如執行gradle helloWorld1,helloWorld2,可簡寫爲gradle hW1,hW2

2.6 條件執行

2.6.1 onlyIf

// gradle hello =>  hello:SKIPPED(條件不知足,不執行)
// onlyIf 經常使用於判斷當前環境是否知足執行條件
version = '1.0'
ext {
    createYear = '2015'
}
task hello << {
    println 'I was Created in ' + createYear 
}
hello.onlyIf { project.hasProperty('createYear') && 
    project.createYear == '2016'}

2.6.2 enabled

// gradle h2 => :hello1 SKIPPED :hello2 Step 2
// 即便2依賴1,1被禁用,2仍能執行
// 經常使用於測試,更換舊代碼
task hello1 << {
    println 'Step 1' 
}
task hello2(dependsOn:hello1) << {
    println 'Step 2'
}
hello1.enabled = false
  • 因爲enabled是task的一個屬性,hello1 能夠寫爲
task hello1 {
    enabled = false;
    doLast { println 'Step 1' }
}

2.7 編譯優化

task hello {
    ext {
        testFile = file('in.txt')
    }
    String outFileName = 'out.txt'
    File outFile = new File(outFileName)
    inputs.file testFile
    outputs.file outFile

    doLast {
        def property = new XmlParser().parse(testFile)
        def key = property.key[0].text()
        def value = property.value[0].text()
        def destFile = new File(outFileName)
        destFile.text = "$key = $value"
    }
}
第一次執行
gradle hello => :hello BUILD SUCCESSFUL
第二次執行 
gradle hello => :hello UP-TO-DATE
  • gradle會自動對輸入輸出操做的task進行編譯優化,例如上面的例子,第一次執行時,須要打開輸入文件,建立輸出文件,當第二次這個命令時,gradle發現輸入輸出文件並無發生變化,所以顯示UP-TO-DATE,即沒有必要執行這個命令了,這在實際項目開發過程當中,將節省大量的時間
  • 當輸入輸出文件發生改變(例如刪除out.txt),任務將從新編譯執行
  • 若是須要強制執行,及時輸入輸出沒有發生改變,能夠使用--rerun-tasks參數
gradle hello --rerun-tasks
// gradle -b build.gradle hello --rerun-tasks
相關文章
相關標籤/搜索