Gradle 深度刨析

基本構建塊

每個 Gradle 構建都包含三個基本概念:project、task 和 property。
每個構建包含至少一個 project、一個或多個 task。project 和 task 暴露的屬性可以用來控制構建。
Gradle 的核心組件直接的依賴關係如下:Gradle 的核心組件直接的依賴關係
在多項目構建中,一個 project 可以依賴於其他的 project 。在同一個 project 中一個 task 可以依賴一個或多個 task。

Project

org.gradle.api.Project 是主要的與 Gradle 構建文件交換的接口,提供了 Gralde 所有特徵的編程訪問方式(例如tTask的創建以及依賴的管理)。在調用對應API時無需使用 project 變量,因爲 Gradle 會默認你使用的是 Project 的實例,

一個 Project 可以創建新的 Task,添加依賴關係和配置,並應用插件和其他的構建腳本。

生命週期

“build.gradle” 文件與Project 實例是一一對應的。在構建初始化時,Gradle 爲每個參與到構建過程的項目都創建了一個 Project 對象,操作如下:

  • 爲構建過程創建一個org.gradle.api.initialization.Settings實例
  • 檢查settings.gradle腳本,如果存在,這對上面創建的Settings實例進行相應的配置
  • 使用Settings實例作爲配置信息創建Project層次的實例
  • 最後,循環檢擦每個相關的項目,如果存在”build.gradle”文件,則根據該文件對項目對應的Project對象進行配置。項目的檢查是橫向進行的,這樣一個項目總是會在其子項目之前進行檢測、配置。這個順序可以通過調用evaluationDependsOnChildren()進行修改、或者通過evaluationDependsOn(String)方法添加一個明確的檢查依賴關係

Tasks(任務)

一個項目基本上是一個Task對象的集合。每個Task的執行一塊兒基本的工作,如編譯類文件,或運行單元測試,或壓縮war文件。我們可以通過實現org.gradle.api.task.TaskContainer接口的類的名爲create的方法(該方法是一個多重載的方法)來添加Task,例如TaskContainer.create(String),還可以使用TaskContainer中的一些方法來查找已經存在的Task,例如TaskCollection.getByName(String)
第一個 Gradle 腳本及簡單命令 的學習中我們對 Task 就已經有過接觸,並且使用過其中一些較爲重要的功能:任務動作(task action)以及任務依賴(task dependency)。

Task action(任務動作)

任務動作定義了一個任務執行時的最小工作單元,可以是簡單的輸出,也可以是諸如編譯等較爲複雜的工作。例如第一個 Gradle 腳本及簡單命令 中的:

task helloworldSort {
    //doLast 就是 Task 中的一個任務動作
    doLast{
        print 'Hello world!'
    }
}
Task dependency(任務依賴)

但一個任務運行時需要先運行另一個任務,這兩個任務間就需要有任務依賴。例如第一個 Gradle 腳本及簡單命令 中的:

// 任務依賴
yayGradle0.dependsOn startSession
/* 任務執行的順序 startSession -> yayGradle0 -> yayGradle1 -> yayGradle2 -> groupTherapy */
// 任務依賴
task groupTherapy(dependsOn: yayGradle2) << {
    println 'groupTherapy'
}

以上就是任務依賴的兩種使用方法。
下面是 Task 的API:
任務Task

Dependencies(依賴項)

一個項目爲了完成構建工作,通常會有數個依賴。此外,項目通常會產生一系列的其他項目可以使用的工件。這些依賴項按配置分組,可以從資料庫檢出或上傳自己的依賴項到資料庫。getConfigurations()方法返回的ConfigurationContainer用於管理配置相關信息。 getDependencies()方法返回的DependencyHandler用來管理依賴項相關信息。 ArtifactHandler.getArtifacts()方法返回管理工件相關信息。 getRepositories()方法返回的RepositoryHandler用來管理存儲庫相關信息。

多項目構建(Multi-project Builds)

多項目會被排成的一個層次結構。一個項目有一個名稱以及能夠唯一標識該層次結構中的完全限定的路徑。

插件(Plugins)

插件可以用於模塊化 以及重用項目配置。可以使用PluginAware.apply(java.util.Map)方法,應用插件或通過使用插件腳本塊。

 plugins {
     id "org.company.myplugin" version "1.3"
 }

以上就是一個簡單的插件腳本塊。

屬性(Properties)

Gradle 執行項目的構建文件來配置對應的Project實例。任何屬性或您的腳本使用的方法是通過授予關聯的Project對象來實現的。這意味着,你可以在您的腳本直接使用Project接口上的任何方法和屬性。
例如︰

 defaultTasks('some-task')  // Project.defaultTasks()
 reportsDir = file('reports') // Project.file() and the Java Plugin

您也可以訪問使用該屬性的實例。在某些情況下,這可以使腳本更清晰。例如,您可以使用project.name來訪問該項目的名稱。
一個項目有 6個屬性 “範圍”用於搜索屬性。您可以通過構建文件中的名稱或通過調用項目的property(String)方法訪問這些屬性。5個屬性“範圍”是:
1. Project對象本身。此範圍包括Project實現類聲明的屬性的getter和setter。例如,getRootProject()可作爲rootProject的屬性訪問方式。此範圍的屬性是可讀或可寫的,存在對相應 getter 和 setter 方法。

  1. 項目的額外屬性。每個項目都維護一個額外屬性的映射,可以包含任意 名稱 - >值 對。一旦定義,該範圍的屬性是可讀和可寫的。有關詳細信息,請參閱其他屬性

  2. 通過添加插件將擴展添加到項目中。每個擴展都是隻讀屬性,與擴展具有相同的名稱。

  3. 通過插件將約定屬性添加到項目中。插件可以通過項目的Convention對象向項目添加屬性和方法。此範圍的屬性可以是可讀或可寫的,這取決於約定對象。

  4. 項目的任務。可以通過使用其名稱作爲屬性名稱來訪問任務。此範圍的屬性是隻讀的。例如,調用的任務compile可作爲compile 屬性訪問。

  5. 繼承自項目父級的額外屬性和慣例屬性,遞歸到根項目。此作用域的屬性爲只讀。

    當讀取屬性時,項目按順序搜索上述範圍,並從其找到屬性的第一個範圍返回值。如果未找到,將拋出異常。查看property(String)更多詳細信息。

    編寫屬性時,項目按順序搜索上述範圍,並將其屬性設置在第一個作用域中,該屬性位於其中。如果未找到,將拋出異常。查看setProperty(String, Object)更多詳細信息。

額外屬性

所有額外的屬性必須通過“ext”命名空間進行定義。一旦額外的屬性被定義,它可以直接在所有的對象(在下面的情況下分別是項目,任務和子項目)可用,並且可以被讀取和更新。只需要在最初宣佈通過命名空間來完成。

project.ext.prop1 = "foo"
 task doStuff {
     ext.prop2 = "bar"
 }
subprojects { ext.${prop3} = false }

通過“ext”或通過擁有的對象來讀取額外的屬性。

ext.isSnapshot = version.endsWith("-SNAPSHOT")
if (isSnapshot) {
     // do snapshot stuff
}

動態方法

一個項目有5種方法“範圍”,它搜索方法:
1. Project對象本身。
2. 構建文件。該項目搜索在構建文件中聲明的匹配方法。
3. 插件添加到項目的擴展。每個擴展可用作接受閉包或Action作爲參數的方法。
4. 通過插件將約定方法添加到項目中。插件可以通過項目的Convention對象向項目添加屬性和方法。
5. 項目的任務。爲每個任務添加一個方法,使用任務的名稱作爲方法名稱並獲取單個閉包或Action參數。該方法Task.configure(groovy.lang.Closure)
6. 使用提供的閉包調用關聯任務的方法。例如,如果項目有一個被調用的任務compile,那麼將添加一個方法,並帶有以下簽名:void compile(Closure configureClosure)。
7. 父項目的方法,遞歸到根項目。
8. 項目的屬性,其值爲閉包。封閉被視爲一種方法,並使用提供的參數進行調用。該物業的位置如上所述。

下面是 Project 的API:
Project API

下面是 PluginAware 的API:

PluginAware API

發佈了79 篇原創文章 · 獲贊 21 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章