Gradle核心思想(六)自定義Gradle外掛的三種方式

劉望舒發表於2019-04-17

本文首發於微信公眾號「劉望舒」

相關文章
Gradle核心思想(一)為什麼現在要用Gradle?
Gradle核心思想(二)Gradle入門前奏
Gradle核心思想(三)Groovy快速入門指南
Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper
Gradle核心思想(五)通俗易懂的Gradle外掛講解

前言

在上一篇文章Gradle核心思想(五)通俗易懂的Gradle外掛講解中,我介紹了什麼是Gradle外掛、如何使用Gradle外掛、Gradle外掛的作用和好處,由於篇幅的原因,還有一個重要的知識點沒有講,那就是自定義Gradle外掛(自定義Gradle物件外掛)。自定義Gradle外掛主要有三種方式,分別是build.gradle中編寫、buildSrc工程專案中編寫、獨立專案中編寫。建議閱讀本文前,先閱讀開頭列出的本系列相關文章。

1.build.gradle

物件外掛是實現了org.gradle.api.plugins介面的外掛,這個介面中只定義個一個簡單的apply方法,想要實現自定義外掛就需要去實現org.gradle.api.plugins介面。 Groovy、Java、Kotlin都可以作為實現外掛的語言,在本文的示例中,使用Groovy作為實現語言。 在實際工作中我們很少會在build.gradle中編寫自定義外掛,這裡是為了帶大家寫個最簡單的例子,可以最快最直接的瞭解什麼是自定義外掛。

1.1 簡單的自定義外掛

這裡使用IntelliJ來編輯(AS也可以),首先新建一個Groovy工程:

Gradle核心思想(六)自定義Gradle外掛的三種方式

定義專案的GroupId和ArtifactId:

3.png

build.gradle

apply plugin:CustomPlugin
class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('CustomPluginTask') {
            doLast {
                println "自定義外掛"
            }
        }
    }
}
複製程式碼

在build.gradle中自定義了一個外掛CustomPlugin,在apply方法中建立一個名稱為CustomPluginTask的任務。在IntelliJ的Terminal中輸入gradlew.bat CustomPluginTask來執行CustomPluginTask任務。

Gradle核心思想(六)自定義Gradle外掛的三種方式

1.2 自定義外掛擴充套件

再舉一個簡單的外掛擴充例子,通過外掛擴充來配置CustomPluginTask的輸出字串,如下所示。 build.gradle

class CustomPluginPluginExtension {
    String message = 'from CustomPlugin'
}
class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        def extension = project.extensions.create('custom', CustomPluginPluginExtension)//1
        project.task('CustomPluginTask') {
            doLast {
                println extension.message
            }
        }
    }
}
apply plugin: CustomPlugin
custom.message = "自定義外掛擴充"//2
複製程式碼

CustomPluginPluginExtension類中定義了message變數,CustomPluginPluginExtension是一個Groovy Bean(類似於JavaBean)。註釋1處用於新增擴充外掛CustomPluginPluginExtension到外掛列表中,名稱為custom。註釋2處設定CustomPluginPluginExtension的message值。 Terminal中輸入gradlew.bat CustomPluginTask來執行CustomPluginTask任務。

Gradle核心思想(六)自定義Gradle外掛的三種方式

2.buildSrc工程專案

除了在build.gradle中編寫的自定義外掛,還可以將外掛的原始碼放在rootProjectDir/buildSrc/src/main/groovy目錄中,Gradle會自動識別來完成編譯和測試。 在第一節的工程根目錄下建立/buildSrc/src/main/groovy目錄,如下圖所示。

Gradle核心思想(六)自定義Gradle外掛的三種方式
在groovy目錄中建立一個groovy檔案,比如我的是CustomPlugin.groovy: buildSrc/src/main/groovy/CustomPlugin.groovy

import org.gradle.api.Plugin;
import org.gradle.api.Project;
class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('CustomPluginTask') {
            doLast {
                println "自定義外掛"
            }
        }
    }
}
複製程式碼

修改build.gradle為如下的內容:
build.gradle

apply plugin: CustomPlugin
複製程式碼

Terminal中輸入gradlew.bat CustomPluginTask來執行CustomPluginTask任務,會列印出我們想要的結果。

3.獨立專案

無論是在build.gradle中編寫自定義外掛,還是buildSrc專案中編寫自定義外掛,都只能在自己的專案中進行使用。如果想要分享給其他人或者自己用,可以在一個獨立的專案中編寫外掛,這個專案會生成一個包含外掛類的JAR檔案,有了JAR檔案就很容易進行分享了。

3.1 自定義外掛

為了和前兩種方式進行區分,用IntelliJ新建一個Groovy工程,我的工程名為CustomPluginShare,後面會用到。 配置build.gradle

apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}
複製程式碼

應用Groovy外掛,並將Gradle API新增為編譯時依賴項,build工程,會在External Libraries中生成三個jar檔案:

Gradle核心思想(六)自定義Gradle外掛的三種方式

這樣我們可以在非buildSrc工程專案中使用groovy語法和Gradle的api了。 建立自定義外掛 在src/main/groovy/ 目錄中建立一個包,我的是com.example.plugins,在com.example.plugins建立一個groovy檔案: src/main/groovy/com/example/plugins/CustomPlugin.groovy

package com.example.plugins
import org.gradle.api.Plugin
import org.gradle.api.Project
class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('CustomPluginTask') {
            doLast {
                println "自定義外掛"
            }
        }
    }
}
複製程式碼

配置properties檔案
在buildSrc工程專案中,Gradle可以自動的去識別外掛,獨立專案中的外掛是如何被Gradle識別的呢?答案是需要在生成的JAR檔案中提供一個屬性檔案,這個屬性檔名要與外掛id相匹配。在resources中建立src/main/resources/META-INF/gradle-plugins/com.example.plugins.customplugin.properties,這個屬性檔案的名稱實際就是外掛的id。將properties檔案的內容改為:

src/main/resources/META-INF/gradle-plugins/com.example.plugins.properties

implementation-class=com.example.plugins.CustomPlugin
複製程式碼

implementation-class屬性為自定義外掛的名稱。
上傳外掛
這裡為了方便舉例直接將外掛上傳到本地,如果想要釋出到Maven、ivy等倉庫,見下面的文件: docs.gradle.org/4.4/usergui… docs.gradle.org/4.4/usergui… 想要釋出到Gradle外掛門戶上,見下面的文件: docs.gradle.org/4.4/usergui… 在build.gradle檔案中新增如下內容:

apply plugin: 'maven'
group = 'com.example.plugins'
version = '1.0.0'
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}
複製程式碼

這段程式碼會將生成的外掛上傳到專案的平級目錄repo下。定義了group和version的名稱,這些值會在其他專案依賴該外掛時用到。我們Build後會在Gradle視窗中看到uploadArchives,如下圖所示。

Gradle核心思想(六)自定義Gradle外掛的三種方式
點選uploadArchives會在本地生成外掛相關的檔案,比如我的目錄和檔案如下圖所示。
Gradle核心思想(六)自定義Gradle外掛的三種方式
圖中的CustomPluginShare-1.0.0.rar就是我們需要的外掛jar包。

3.2 在另一個專案中使用外掛

新建一個Groovy專案,我取名為Projet,build.gradle的程式碼如下:

apply plugin: 'com.example.plugins.customplugin'

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath 'com.example.plugins:CustomPluginShare:1.0.0'
    }
}
複製程式碼

其中com.example.plugins是group,CustomPluginShare是自定義外掛的名稱,1.0.0是版本號,也可以這麼寫:

   dependencies {
        classpath group: 'com.example.plugins', name: 'CustomPluginShare',
                version: '1.0.0'
    }
複製程式碼

Terminal中輸入gradlew.bat CustomPluginTask來執行CustomPluginTask任務,大功告成。 如果我們將自定義外掛釋出到Gradle外掛門戶上,就可以使用外掛DSL了:
build.gradle

plugins {
    id 'com.example.plugins.customplugin' version '1.0.0'
}
複製程式碼

雖然講解獨立專案的例子超級簡單,但我還是將程式碼上傳到GitHub上了,也許會有同學用的上: github.com/henrymorgen…

總結

本篇文章介紹了自定義Gradle外掛的3種方式,旨在以最簡單的例子來讓大家快速掌握,如果還想了解複雜的自定義外掛可以去檢視一些開源的Gradle外掛,或者在工作中去實踐。本篇文章也為學習Android Gradle外掛打下了伏筆。


不僅分享大前端、Java、Android、跨平臺等技術,還有大廠乾貨和程式設計師成長類文章。

Gradle核心思想(六)自定義Gradle外掛的三種方式

相關文章