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

相關文章
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工程:

定義項目的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任務。

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任務。

2.buildSrc工程項目

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

在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文件:

這樣我們可以在非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等倉庫,見下面的文檔:
https://docs.gradle.org/4.4/userguide/publishing_ivy.html
https://docs.gradle.org/4.4/userguide/publishing_maven.html
想要發佈到Gradle插件門戶上,見下面的文檔:
https://docs.gradle.org/4.4/userguide/plugins.html#sec:plugins_block
在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,如下圖所示。

點擊uploadArchives會在本地生成插件相關的文件,比如我的目錄和文件如下圖所示。

圖中的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上了,也許會有同學用的上:
https://github.com/henrymorgen/CustomPlugin

總結

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


分享大前端、Java、跨平臺等技術,關注職業發展和行業動態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章