使用外掛程式
Gradle 的許多功能都是透過外掛提供的,包括與 Gradle 一起發布的核心外掛、第三方外掛,以及在建置中定義的腳本外掛。
外掛會引入新的任務(例如 JavaCompile
)、網域物件(例如 SourceSet
)、慣例(例如將 Java 原始碼定位在 src/main/java
),並擴充核心或其他外掛物件。
Gradle 中的外掛對於自動化常見的建置任務、與外部工具或服務整合,以及根據特定專案需求調整建置流程至關重要。它們也作為組織建置邏輯的主要機制。
外掛的優點
在建置腳本中撰寫許多任務並複製設定區塊可能會很混亂。與直接將邏輯新增到建置腳本相比,外掛提供了多項優點
-
促進可重複使用性:減少在專案中重複類似邏輯的需求。
-
增強模組化:允許更模組化和有組織的建置腳本。
-
封裝邏輯:將命令式邏輯分開,讓建置腳本更具宣告性。
外掛分發
您可以利用 Gradle 和 Gradle 社群的外掛,或建立自己的外掛。
外掛有下列三種取得方式
-
核心外掛 - Gradle 開發並維護一組 核心外掛。
-
社群外掛 - 在遠端儲存庫中分享的 Gradle 外掛,例如 Maven 或 Gradle 外掛入口。
-
本機外掛 - Gradle 讓使用者能夠使用 API 建立自訂外掛。
外掛類型
外掛可以實作為二進位外掛、預編譯腳本外掛或腳本外掛
- 二進位外掛
-
二進位外掛是編譯外掛,通常以 Java 或 Kotlin DSL 編寫,並封裝為 JAR 檔案。它們使用
plugins {}
區塊套用至專案。與腳本外掛或預編譯腳本外掛相比,它們提供更好的效能和可維護性。 - 預編譯腳本外掛
-
預編譯腳本外掛是 Groovy DSL 或 Kotlin DSL 腳本,編譯並分發為封裝在函式庫中的 Java 類別檔案。它們使用
plugins {}
區塊套用至專案。它們提供一種在專案間重複使用複雜邏輯的方式,並允許更佳地組織建置邏輯。 - 腳本外掛
-
腳本外掛是 Groovy DSL 或 Kotlin DSL 腳本,使用
apply from:
語法直接套用至 Gradle 建置腳本。它們在建置腳本中內嵌套用,以新增功能或自訂建置程序。它們易於使用。
外掛通常從腳本外掛開始(因為它們易於撰寫)。然後,隨著程式碼變得更有價值,它會移轉至二進位外掛,以便在多個專案或組織間輕鬆測試和分享。
使用外掛
若要使用外掛中封裝的建置邏輯,Gradle 需要執行兩個步驟。首先,它需要解析外掛,然後它需要套用外掛至目標,通常是 專案
。
-
解析外掛表示找出包含特定外掛的 JAR 正確版本,並將其加入指令碼類別路徑。一旦解析外掛,其 API 便可在建置指令碼中使用。指令碼外掛會自行解析,因為它們會從套用時提供的特定檔案路徑或 URL 中解析。作為 Gradle 發行版一部分提供的核心二進制外掛會自動解析。
-
套用外掛表示在專案上執行外掛的 Plugin.apply(T)。
建議使用 外掛 DSL,以便一次解析並套用外掛。
解析外掛
Gradle 提供 核心外掛(例如 JavaPlugin
、GroovyPlugin
、MavenPublishPlugin
等)作為其發行版的一部分,這表示它們會自動解析。
核心外掛會使用外掛名稱在建置指令碼中套用
plugins {
id «plugin name»
}
例如
plugins {
id("java")
}
非核心外掛必須在套用之前解析。非核心外掛會以建置檔案中的唯一 ID 和版本進行識別
plugins {
id «plugin id» version «plugin version»
}
並且必須在設定檔中指定外掛的位置
pluginManagement {
repositories {
gradlePluginPortal()
}
maven {
url 'https://maven.example.com/plugins'
}
}
解析和套用外掛還有其他考量因素
# | 若要 | 使用 | 例如 |
---|---|---|---|
將 核心、社群或 本機外掛套用至特定專案。 |
|
||
將共用的 核心、社群或 本機外掛套用至多個子專案。 |
|
||
套用 核心、社群或 本機外掛,針對建置指令碼本身。 |
|
||
套用 本機指令碼外掛。 |
|
1. 使用 plugins{}
區塊套用外掛
外掛 DSL 提供簡潔且便利的方式來宣告外掛相依性。
外掛區塊設定 PluginDependenciesSpec
的執行個體
plugins {
application // by name
java // by name
id("java") // by id - recommended
id("org.jetbrains.kotlin.jvm") version "1.9.0" // by id - recommended
}
核心 Gradle 外掛很特別,因為它們提供簡短名稱,例如核心 JavaPlugin 的 java
。
若要套用核心外掛,可以使用簡短的 名稱
plugins {
java
}
plugins {
id 'java'
}
所有其他二進制外掛都必須使用外掛 ID 的完全限定形式(例如,com.github.foo.bar
)。
若要套用 Gradle 外掛入口 中的社群外掛,必須使用完全限定的外掛 ID,也就是全球唯一的識別碼
plugins {
id("com.jfrog.bintray") version "1.8.5"
}
plugins {
id 'com.jfrog.bintray' version '1.8.5'
}
請參閱 PluginDependenciesSpec
,以取得有關使用外掛 DSL 的更多資訊。
外掛 DSL 的限制
外掛 DSL 為使用者提供方便的語法,並讓 Gradle 能夠快速判斷使用哪些外掛。這讓 Gradle 能夠
-
最佳化外掛類別的載入和重複使用。
-
提供編輯器有關建置指令碼中潛在屬性和值的詳細資訊。
不過,DSL 要求外掛必須以靜態方式定義。
plugins {}
區塊機制和「傳統」apply()
方法機制之間有一些關鍵差異。還有一些限制和可能的限制。
受限語法
plugins {}
區塊不支援任意程式碼。
它受到約束,必須是冪等(每次產生相同的結果)且沒有副作用(Gradle 可以隨時安全執行)。
格式為
plugins {
id(«plugin id») (1)
id(«plugin id») version «plugin version» (2)
}
1 | 針對核心 Gradle 外掛或建置指令碼中已有的外掛 |
2 | 針對需要解析的二進制 Gradle 外掛 |
plugins {
id «plugin id» (1)
id «plugin id» version «plugin version» (2)
}
1 | 針對核心 Gradle 外掛或建置指令碼中已有的外掛 |
2 | 針對需要解析的二進制 Gradle 外掛 |
其中 «plugin id»
和 «plugin version»
為字串。
其中 «plugin id»
和 «plugin version»
必須是常數、字面字串。
plugins{}
區塊也必須是建置指令碼中的頂層陳述式。它不能巢狀在其他結構內(例如,if 陳述式或 for 迴圈)。
僅限於建置指令碼和設定檔
plugins{}
區塊只能用於專案的建置指令碼 build.gradle(.kts)
和 settings.gradle(.kts)
檔。它必須出現在任何其他區塊之前。它不能用於指令碼外掛或初始化指令碼。
套用外掛至所有子專案
假設您有一個 多專案建置,您可能想要將外掛套用至建置中部分或全部的子專案,但不要套用至根目錄
專案。
雖然 plugins{}
區塊的預設行為是立即 resolve
和 apply
外掛程式,但你可以使用 apply false
語法告訴 Gradle 不要將外掛程式套用至目前的專案。然後,在子專案的建置指令碼中使用沒有版本的 plugins{}
區塊
include("hello-a")
include("hello-b")
include("goodbye-c")
plugins {
id("com.example.hello") version "1.0.0" apply false
id("com.example.goodbye") version "1.0.0" apply false
}
plugins {
id("com.example.hello")
}
plugins {
id("com.example.hello")
}
plugins {
id("com.example.goodbye")
}
include 'hello-a'
include 'hello-b'
include 'goodbye-c'
plugins {
id 'com.example.hello' version '1.0.0' apply false
id 'com.example.goodbye' version '1.0.0' apply false
}
plugins {
id 'com.example.hello'
}
plugins {
id 'com.example.hello'
}
plugins {
id 'com.example.goodbye'
}
你也可以封裝外部外掛程式的版本,方法是使用你自己的 慣例外掛程式 組合建置邏輯。
2. 從 buildSrc
目錄套用外掛程式
buildSrc
是 Gradle 專案根目錄中一個選用的目錄,其中包含用於建置主專案的建置邏輯(例如外掛程式)。只要專案的 buildSrc
目錄中存在已定義 ID 的外掛程式,你就可以套用這些外掛程式。
以下範例說明如何將定義在 buildSrc
中的外掛程式實作類別 my.MyPlugin
繫結至 ID "my-plugin"
plugins {
`java-gradle-plugin`
}
gradlePlugin {
plugins {
create("myPlugins") {
id = "my-plugin"
implementationClass = "my.MyPlugin"
}
}
}
plugins {
id 'java-gradle-plugin'
}
gradlePlugin {
plugins {
myPlugins {
id = 'my-plugin'
implementationClass = 'my.MyPlugin'
}
}
}
然後可以按 ID 套用外掛程式
plugins {
id("my-plugin")
}
plugins {
id 'my-plugin'
}
3. 使用 buildscript{}
區塊套用外掛程式
buildscript
區塊用於
-
建置專案所需的全球
dependencies
和repositories
(套用至子專案)。 -
宣告哪些外掛程式可供 建置指令碼(在
build.gradle(.kts)
檔案本身)使用。
因此,當你想要在建置指令碼本身中使用函式庫時,你必須使用 buildScript
在指令碼類別路徑中新增這個函式庫
import org.apache.commons.codec.binary.Base64
buildscript {
repositories { // this is where the plugins are located
mavenCentral()
google()
}
dependencies { // these are the plugins that can be used in subprojects or in the build file itself
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2' // used in the task below
classpath 'com.android.tools.build:gradle:4.1.0' // used in subproject
}
}
tasks.register('encode') {
doLast {
def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
println new String(encodedString)
}
}
你可以在需要它的子專案中套用全球宣告的相依性
plugins {
id 'com.android.application'
}
可以透過將外掛程式新增至建置指令碼類別路徑,然後套用外掛程式,將以外部 jar 檔案發佈的二進位外掛程式新增至專案。
可以如 建置指令碼的外部相依性 中所述,使用 buildscript{}
區塊將外部 jar 新增至建置指令碼類別路徑
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5")
}
}
apply(plugin = "com.jfrog.bintray")
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
}
}
apply plugin: 'com.jfrog.bintray'
4. 使用舊版 apply()
方法套用指令碼外掛程式
指令碼外掛程式是一個臨時外掛程式,通常會寫在與 build.gradle
檔案位於同一個目錄中,並在該檔案中套用。它會使用 舊版套用方法 套用
class MyPlugin : Plugin<Project> {
override fun apply(project: Project) {
println("Plugin ${this.javaClass.simpleName} applied on ${project.name}")
}
}
apply<MyPlugin>()
我們來看一個寫在名為 other.gradle
的檔案中的外掛程式基本範例,這個檔案位於與 build.gradle
檔案相同的目錄中
public class Other implements Plugin<Project> {
@Override
void apply(Project project) {
// Does something
}
}
首先,使用以下方式匯入外部檔案
apply from: 'other.gradle'
然後您可以套用它
apply plugin: Other
指令碼外掛程式會自動解析,且可以從本機檔案系統或遠端套用指令碼
apply(from = "other.gradle.kts")
apply from: 'other.gradle'
檔案系統位置相對於專案目錄,而遠端指令碼位置則以 HTTP URL 指定。可以將多個指令碼外掛程式(任何形式)套用至特定目標。
外掛程式管理
pluginManagement{}
區塊用於設定外掛程式解析的存放庫,並定義在建置指令碼中套用的外掛程式版本限制。
pluginManagement{}
區塊可以在 settings.gradle(.kts)
檔案中使用,其中它必須是檔案中的第一個區塊
pluginManagement {
plugins {
}
resolutionStrategy {
}
repositories {
}
}
rootProject.name = "plugin-management"
pluginManagement {
plugins {
}
resolutionStrategy {
}
repositories {
}
}
rootProject.name = 'plugin-management'
此區塊也可以在 初始化指令碼 中使用
settingsEvaluated {
pluginManagement {
plugins {
}
resolutionStrategy {
}
repositories {
}
}
}
settingsEvaluated { settings ->
settings.pluginManagement {
plugins {
}
resolutionStrategy {
}
repositories {
}
}
}
自訂外掛程式存放庫
預設情況下,plugins{}
DSL 會從公開的 Gradle 外掛程式入口網站 解析外掛程式。
許多建置作者也希望從私人的 Maven 或 Ivy 存放庫解析外掛程式,因為它們包含專有的實作詳細資料,或希望更能控制哪些外掛程式可供其建置使用。
若要指定自訂外掛程式存放庫,請在 pluginManagement{}
內部使用 repositories{}
區塊
pluginManagement {
repositories {
maven(url = "./maven-repo")
gradlePluginPortal()
ivy(url = "./ivy-repo")
}
}
pluginManagement {
repositories {
maven {
url './maven-repo'
}
gradlePluginPortal()
ivy {
url './ivy-repo'
}
}
}
這會指示 Gradle 在解析外掛程式時,先查看 ../maven-repo
中的 Maven 存放庫,然後如果在 Maven 存放庫中找不到外掛程式,再查看 Gradle 外掛程式入口網站。如果您不希望搜尋 Gradle 外掛程式入口網站,請略過 gradlePluginPortal()
行。最後,將會查看 ../ivy-repo
中的 Ivy 存放庫。
外掛程式版本管理
pluginManagement{}
內部的 plugins{}
區塊允許在單一位置定義建置的所有外掛程式版本。然後,外掛程式可以透過 plugins{}
區塊以 ID 套用至任何建置指令碼。
設定外掛版本的方式有一個好處,就是 pluginManagement.plugins{}
沒有與建置指令碼 plugins{}
區塊相同的 受限語法。這允許外掛版本從 gradle.properties
取得,或透過其他機制載入。
透過 pluginManagement
管理外掛版本
pluginManagement {
val helloPluginVersion: String by settings
plugins {
id("com.example.hello") version "${helloPluginVersion}"
}
}
plugins {
id("com.example.hello")
}
helloPluginVersion=1.0.0
pluginManagement {
plugins {
id 'com.example.hello' version "${helloPluginVersion}"
}
}
plugins {
id 'com.example.hello'
}
helloPluginVersion=1.0.0
外掛版本從 gradle.properties
載入,並在設定指令碼中設定,允許外掛新增至任何專案,而不需要指定版本。
外掛解析規則
外掛解析規則允許您修改 plugins{}
區塊中提出的外掛要求,例如變更請求的版本或明確指定實作人工製品座標。
如需新增解析規則,請在 pluginManagement{}
區塊內使用 resolutionStrategy{}
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == "com.example") {
useModule("com.example:sample-plugins:1.0.0")
}
}
}
repositories {
maven {
url = uri("./maven-repo")
}
gradlePluginPortal()
ivy {
url = uri("./ivy-repo")
}
}
}
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == 'com.example') {
useModule('com.example:sample-plugins:1.0.0')
}
}
}
repositories {
maven {
url './maven-repo'
}
gradlePluginPortal()
ivy {
url './ivy-repo'
}
}
}
這會指示 Gradle 使用指定的實作人工製品,而不是從外掛 ID 到 Maven/Ivy 座標的內建預設對應。
自訂 Maven 和 Ivy 外掛儲存庫必須包含 外掛標記人工製品 和實作外掛的人工製品。請參閱 Gradle 外掛開發外掛,以取得更多關於發佈外掛至自訂儲存庫的資訊。
請參閱 PluginManagementSpec,以取得使用 pluginManagement{}
區塊的完整文件。
外掛標記人工製品
由於 plugins{}
DSL 區塊只允許透過其全球唯一外掛 id
和 version
屬性宣告外掛,因此 Gradle 需要一種方式來查詢外掛實作人工製品的座標。
為此,Gradle 會尋找座標為 plugin.id:plugin.id.gradle.plugin:plugin.version
的外掛標記人工製品。此標記需要有對實際外掛實作的依賴關係。發佈這些標記會由 java-gradle-plugin 自動執行。
例如,sample-plugins
專案中的下列完整範例顯示如何使用 java-gradle-plugin、maven-publish 和 ivy-publish 外掛結合,將 com.example.hello
外掛和 com.example.goodbye
外掛同時發佈到 Ivy 和 Maven 儲存庫。
plugins {
`java-gradle-plugin`
`maven-publish`
`ivy-publish`
}
group = "com.example"
version = "1.0.0"
gradlePlugin {
plugins {
create("hello") {
id = "com.example.hello"
implementationClass = "com.example.hello.HelloPlugin"
}
create("goodbye") {
id = "com.example.goodbye"
implementationClass = "com.example.goodbye.GoodbyePlugin"
}
}
}
publishing {
repositories {
maven {
url = uri(layout.buildDirectory.dir("maven-repo"))
}
ivy {
url = uri(layout.buildDirectory.dir("ivy-repo"))
}
}
}
plugins {
id 'java-gradle-plugin'
id 'maven-publish'
id 'ivy-publish'
}
group 'com.example'
version '1.0.0'
gradlePlugin {
plugins {
hello {
id = 'com.example.hello'
implementationClass = 'com.example.hello.HelloPlugin'
}
goodbye {
id = 'com.example.goodbye'
implementationClass = 'com.example.goodbye.GoodbyePlugin'
}
}
}
publishing {
repositories {
maven {
url layout.buildDirectory.dir("maven-repo")
}
ivy {
url layout.buildDirectory.dir("ivy-repo")
}
}
}
在範例目錄中執行 gradle publish
會建立下列 Maven 儲存庫配置(Ivy 配置類似)

舊版外掛應用程式
隨著 plugins DSL 的推出,使用者幾乎沒有理由使用舊版外掛應用程式的方法。如果建置作者無法使用外掛 DSL,因為它目前運作方式的限制,我們在此提供說明。
apply(plugin = "java")
apply plugin: 'java'
可以使用外掛 ID 應用外掛。在上述情況中,我們使用簡稱「java」來應用 JavaPlugin。
除了使用外掛 ID,也可以透過指定外掛類別來應用外掛
apply<JavaPlugin>()
apply plugin: JavaPlugin
上述範例中的 JavaPlugin
符號是指 JavaPlugin。這個類別不需要特別匯入,因為 org.gradle.api.plugins
套件會自動匯入所有建置指令碼(請參閱 預設匯入)。
此外,需要附加 ::class
後綴字元來識別 Kotlin 中的類別文字,而不是 Java 中的 .class
。
此外,不需要附加 .class
來識別 Groovy 中的類別文字,因為它在 Java 中是這樣。
使用版本目錄
當專案使用版本目錄時,可以在應用時透過別名來參照外掛。
我們來看一個簡單的版本目錄
[versions]
intellij-plugin = "1.6"
[plugins]
jetbrains-intellij = { id = "org.jetbrains.intellij", version.ref = "intellij-plugin" }
然後可以使用 alias
方法將外掛應用到任何建置指令碼
plugins {
alias(libs.plugins.jetbrains.intellij)
}
jetbrains-intellij 可用作 Gradle 產生的安全存取器:jetbrains.intellij 。
|
下一步: 了解如何撰寫外掛 >>