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


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

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

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.11

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM