学习如何使用Gradle的插件(plugin)。该学习记录基于Gradle官方网站资料。本篇参考链接如下:
https://docs.gradle.org/current/userguide/plugins.html
Gradle的核心只提供了很少的功能。为了实现更加复杂的功能,需要依赖各种插件。比如编译java文件的功能就是由插件提供。插件会给Gradle增加各种任务类型(如JavaCompile),区域对象(如SourceSet),规约(如java的代码默认存放在src/main/java)。另外,有些插件还会扩展Gradle的核心功能。
1.插件的种类
脚本插件
脚本插件一般可以对构建进行更加深入的操作。它们的典型用法是直接在构建脚本(build.gradle)中使用。
apply from: 'other.gradle'
脚本插件可以是本地的也可以是远程的。调用本地插件需要使用相对路径,调用远程插件需要使用Http Url。
二进制插件
二进制插件是一些实现了Plugin接口的类。它们存在于插件jar包内。构建脚本可以直接调用二进制插件的方法或者属性。
在构建脚本中,通过插件id来调用二进制插件。普通的插件id格式如:com.github.foo.bar。但是Gradle的核心插件id都比较短。比如“java”是JavaPlugin的id。
二进制插件的介绍比较长,所以作为第二大部分。
2.二进制插件
通过插件DSL调用二进制插件
调用核心二进制插件
plugins { id 'java'}
调用普通二进制插件
plugins { id 'com.jfrog.bintray' version '0.4.1'}
插件DSL(plugins{})的限制
- 语法受限
为了实现幂等(每次执行结果都相同)和减少副作用,plugins{}不支持变量。plugins{}的普通形式如下。
plugins { id «plugin id» // (1) id «plugin id» version «plugin version» [apply «false»] // (2) }
(1)是核心插件的声明方式
(2)是普通插件的声明方式
«plugin id»与«plugin version»必须是不可变字符串。(2)的apply是一个可选的布尔型属性。为false的时候会使插件不被即时加载(比如只想让子工程加载)。
- plugins{}必须放在构建脚本的最上方。它不能被放在其他的逻辑结构中,如if,for循环等。
- plugins{}只能用在构建脚本里,而不能用在脚本插件或者settings.gradle文件中。(未来版本的Gradle可能会去除这个限制)
- 如果因plugins{}限制过多造成使用不便,可以使用buildscript{}。后面会学习。
- 为子工程引入插件
有些项目需求需要多工程。每个工程需要的插件不同,plugins{}只能通过把apply设定为false来实现。
主工程MainProject的settings.gradle文件
include 'ChildProjectA' include 'ChildProjectB' include 'SpecialChildProject
主工程MainProject的build.gradle文件
plugins { id 'org.gradle.sample.hello' version '1.0.0' apply false id 'org.gradle.sample.goodbye' version '1.0.0' apply false } subprojects { if (name.startsWith('Child')) { apply plugin: 'org.gradle.sample.hello' } }
子工程build.gradle文件
plugins {
id 'org.gradle.sample.goodbye'
}
上面的例子在本地环境无法执行。因为不存在hello与goodbye插件。但是官网的结果应该可信。如下:
$gradle hello
:ChildProjectA:hello
:ChildProjectB:hello
Hello!
Hello!
BUILD SUCCEEDED
说明子工程ChildProjectA和ChildProjectB引入了hello插件。
- 从工程的buildSrc中引入插件。
首先需要在buildSrc文件夹中的build.gradle脚本中声明插件
plugins { id 'java' id 'java-gradle-plugin' } gradlePlugin { plugins { myPlugins { id = 'my-plugin' implementationClass = 'my.MyPlugin' } } } dependencies { compileOnly gradleApi() }
然后在构建脚本中正常使用
plugins { id 'my-plugin' }
※还没有学习建立自定义插件,所以这个例子没有在本地执行。之后学习展开。
插件管理
插件管理的DSL是pluginManagement{}。它只能声明在settings.gradle或者init.gradle中。
普通的plugin{}只能引入在Gradle注册过的插件。有时候我们需要引入自定义的插件或者Maven/ivy仓库中的插件。需要通过pluginManagement{}来实现。
settings.gradle
pluginManagement { // 指定仓库时需要用到repositories{} repositories { // 首先到这个本地仓库查找插件 maven { // 这是定义在本地的仓库 url '../maven-repo' } // 如果插件不存在则会继续自动去Gralde plugin portal查找 // 不希望自动去Gradle plugin portal查找的时候,需要删除下面的gradlePluginPortal()语句。 gradlePluginPortal() // 最后到如下仓库中查找插件 ivy { url '../ivy-repo' } }}
插件解析规则
Settins.gradle
pluginManagement { resolutionStrategy { // 判断每一个插件 eachPlugin { // 如果插件的命名控件如下,则无视。转而使用if内的插件 if (requested.id.namespace == 'org.gradle.sample') { useModule('org.gradle.sample:sample-plugins:1.0.0') } } } repositories { maven { url '../maven-repo' } gradlePluginPortal() ivy { url '../ivy-repo' } }}
发布自定义插件
下面的示例简单介绍了一下如何发布自定义插件。笔者的环境下正常执行了下面的脚本,发布了maven插件。 ivy发布也可以执行,为了简单ivy发布被注释了。
首先使用如下命令Gradle初始化一个java工程
$gradle init --type java-library --project-name jvm-library
把根目录下的build.gradle文件内容替换成如下内容
plugins { id 'java-gradle-plugin' id 'maven-publish'}group 'org.gradle.sample'version '1.0.0'gradlePlugin { plugins { hello { id = 'org.gradle.sample.hello' implementationClass = 'org.gradle.sample.hello.HelloPlugin' } }}publishing { repositories { maven { url 'consuming/maven-repo' } }}
在工程的src/main/java文件夹下建立org.gradle.sample.hello包,在新建的包下建立HelloPlugin.java文件,内容如下:
package org.gradle.sample.hello;public class HelloPlugin {public static void main(String[] args) {System.out.println("Hello class");}}
使用如下命令build这个java工程
$gradle build
之后使用如下命令发布插件
$gradle publish
执行之后,在工程的根目录的consuming/maven-repo文件夹下生成了插件文件。插件的jar文件在另外的文件夹。当然这个插件只是一个示例,引入到其他工程也不会产生任何作用。

旧版本引入插件的方法
有时候plugin{}因为一些显示没有办法引入想要的插件时可以尝试使用旧版本的插件引入方法
// 使用插件名引入apply plugin: 'java'// 使用插件类引入,类可以不带.class扩展名。// 另外JavaPlugin的真身是org.gradle.api.plugins。// 它是核心插件, 所以可以使用简化名称。apply plugin: JavaPlugin
使用buildscript{}来引入插件
如果二进制插件已经作为jar被发布了,可以用buildscript来引入。
buildscript { repositories { jcenter() } // 这里出现了依赖。 后续会学习到。 dependencies { classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:0.4.1' }}apply plugin: 'com.jfrog.bintray'