使用 Java 开发 Gradle 插件
Gradle 插件代码可以在 build.gradle 中,buildSrc 项目中,以及独立的插件项目中编写。本文将介绍如何在一个独立的项目中使用 Java 语言编写 Gradle 插件,并发布到仓库中。
1 创建项目
Gradle 插件项目和普通的 Java 项目没有什么不同,普通项目是基于其它三方包进行开发,而 Gradle 插件项目基于 Gradle 的 API 进行开发。
基于 Gradle 创建一个 Java 项目,项目目录结构如下,和普通项目一样。
gradle-plugin-sample
|
├───build.gradle
├───settings.gradle
└───src
├───main
│ ├───java
│ └───resources
└───test
├───java
└───resources
引入 Gradle API 相关的 jar 包。为了方便起见,可以通过 gradle 插件 java-gradle-plugin 来引入 Java 插件,引入 Gradle API 相关依赖以及生成插件相关的描述符。
build.gradle
plugins {
id 'java-gradle-plugin'
}
group 'com.robothy'
version '1.0-SNAPSHOT'
repositories {
mavenLocal()
mavenCentral()
}
wrapper{
gradleVersion = '6.7'
}
2 动手开发
项目创建好之后,就可以开始动手开发了。从项目构建角度来看,Gradle 插件是一段可重用的构建逻辑,这段逻辑能够被应用到各个项目当中。更具体来说,Gradle 插件是一个实现了 org.gradle.api.Plugin 接口的类,它被 Project (可以认为是 build.gralde, 它本质是一个实现了 Project 接口的类)所引用。开发插件的本质就是往 build.gradle 中插入一段逻辑。
void apply(T target)
Plugin 是一个泛型接口,有一个抽象方法 apply,它的参数类型可以是 Project, Settings, 或者 Gradle。
类型为 Project,插件可以应用于 build.gradle;
类型为 Settings,插件可应用于 settings.gradle;
类型为 Gradle, 插件可应用于 Gradle 初始化脚本。
在应用插件时,gradle 会创建一个插件类的实例,并调用 apply 方法。因此,插件的逻辑就是 apply 方法中的代码。
一个独立的项目中可以有多个实现了 Plugin 接口的类,意味着一个项目可以包含多个插件。每一个插件都需要在 build.gradle 中添加相应的描述,java-gradle-plugin 会根据这些描述生成插件描述符(jar 包中的一个文件)。
假设要在 gradle-plugin-sample 项目中创建两个插件 hello, goodbye,需要进行如下两个步骤:
1)创建插件类
HelloPlugin.java
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class HelloPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
System.out.println("Message from hello plugin.");
}
}
GoodbyePlugin.java
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class GoodbyePlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
System.out.println("Message from goodbye plugin.");
}
}
2)在 build.gradle 中添加描述内容
描述内容需要指定插件的 ID 和插件的入口类。
gradlePlugin {
plugins {
helloPlugin {
id = 'com.robothy.hello'
implementationClass = 'com.robothy.HelloPlugin'
}
googbyePlugin{
id = 'com.robothy.goodbye'
implementationClass = 'com.robothy.GoodbyePlugin'
}
}
}
完成上面步骤之后,一个简单的插件就算完成了开发,接下来就可以发布和使用了。
3 发布插件
插件可以发布到 Maven 仓库和 Gradle 官方插件门户。
3.1 发布到 Maven 仓库
发布插件到 Maven 仓库和发布普通的 jar 包一样,需要用到 maven-publish 插件。要发布到远程 Maven 仓库可能需要提供认证信息,这里简单起见只发布到本地仓库。
1)在 build.gradle 文件中添加 maven-publish 插件
plugins {
id 'java-gradle-plugin'
id 'maven-publish'
}
2)执行 gradle publishToMavenLocal,成功之后可以在 ~/.m2 目录下找打发布的 jar 包。
要使用发布到 Maven 仓库中的 Gradle 插件,需要先在 settings.gradle 中指定仓库。如下代码指定了插件仓库有本地 Maven 和 Gradle 插件门户。
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
3.2 发布到 Gradle 官方插件门户
我们平常使用的大部分插件来自于 Gradle 官方插件门户,开发人员注册一个 Gradle 账号之后可以将插件发布到门户,这样其他人就可以很方便地使用了。按照如下步骤发布插件,这里如果没有描述清楚可以移步 Gradle 官网文档:How do I add my plugin to the plugin portal?。
1)注册门户账户
2)创建 API Key。注册好账户就能够看见了。
3)将 API Key 添加到文件 ~/.gradle/gradle.properties
4)使用插件发布插件 com.gradle.plugin-publish 发布插件(不是病句,只是有点绕 )
将 com.gradle.plugin-publish 添加到插件项目 gradle-plugin-sample 的 build.gradle 中,然后添加插件的描述信息。
pluginBundle {
website = 'http://www.gradle.org/'
vcsUrl = 'https://github.com/gradle/gradle'
description = 'Greetings from here!'
tags = ['greetings', 'salutations']
plugins {
greetingsPlugin {
// id='com.robothy.hello' 可以省略,因为在 gradlePlugin 配置块中已经有 id 信息了
displayName = 'Hello Plugin'
}
}
}
5)使用 gradle publishPlugins 发布插件
如果插件信息描述正确,执行 puhlishPlugins 任务之后会打印出待审核的信息,之后就是等待了(本人发布的插件 com.robothy.cn-repo 经过了四五个小时就审核通过了)。
Publishing plugin com.robothy.cn-repo version 1.0
Thank you. Your new plugin com.robothy.cn-repo has been submitted for approval by Gradle engineers. The request should be processed within the next few days, at which point you will be contacted via email.
4 更多
4.1 在插件中添加任务
先自定义一个 Gradle 任务类 SayHelloTask,该任务的行为是简答的打印固定的字符串。自定义任务需要继承 DefaultTask。
public class SayHelloTask {
@TaskAction
public void hello() {
System.out.println("Hello, World!");
}
}
然后通过 project 往项目中注册一个 SayHelloTask 的实例,任务名为 task。
public class HelloPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
System.out.println("Message from hello plugin.");
project.getTasks().register("hello", SayHelloTask.class);
}
}
当然,也可以在使用 HelloPlugin 插件的 build.gradle 中注册任务。
task hello(type: com.robothy.SayHelloTask)
重新发布插件,执行下面命令时控制台会打印出 "Hello, World!"。
gradle hello
4.2 添加扩展
Gradle 插件可以往 project 中注册扩展,开发人员可以通过扩展设置一些参数值,以供其它的 Gradle Task 使用。假设我们希望在 build.gradle 中添加如下配置信息。
user {
name = 'Robothy'
country = 'China'
}
首先,创建一个配置信息接口,接口中只包含 getter 抽象方法。需要注意的是,返回的类型为 Property,并非直接返回 String。配置信息不需要创建为 Java 类,Gradle 在运行时会通过动态代理的方式自动往代理对象中注入值。
public interface User {
Property<String> getName();
Property<String> getCountry();
}
然后插件就可以往 project 中添加一个扩展了。
project.getExtensions().add("user", User.class);
重新发布插件,此时引入了插件的项目就可以在 builde.gradle 中添加本小节开头描述的配置块了。
Gradle 任务可以通过如下方式访问到这些配置信息。
User user = (User) (project.getExtensions().getByName("user"));
5 小结
本文主要介绍了如何使用纯 Java 语言在一个独立的项目中编写 Gradle 插件,插件主要通过通过传入的 project 参数访问项目,往项目的构建生命周期中插入一些逻辑或者添加配置信息。插件可以发布到私有的 Maven 仓库,也可以发布到 Gradle 插件门户。插件项目中还可以很好地封装一些 Gradle Task,定义一些配置类型。
6 参考内容
[2] How do I add my plugin to the plugin portal?
[3] Developing Custom Gradle Plugins
使用 Java 开发 Gradle 插件的更多相关文章
- 怎样使用Android Studio开发Gradle插件
缘由 首先说明一下为什么会有这篇文章.前段时间,插件化以及热修复的技术非常热,Nuwa热修复的工具NuwaGradle,携程动态载入技术DynamicAPK,还有希望做最轻巧的插件化框架的Small. ...
- eclipse安装阿里巴巴java开发规范插件
阿里巴巴java开发规范插件 作为JAVA开发人员,始终没有一个明确的规范,何为好代码,何为坏代码,造成不同人的代码风格不同,接手别人代码后改造起来相当困难.前不久,阿里巴巴发布了<阿里巴巴Ja ...
- Java开发IDEA插件推荐
IDEA插件推荐 Alibaba Java Coding Guidelines MyBatisCodeHelper-Pro Lombok GsonFormat AceJump Statistic Tr ...
- IDEA Java开发常用插件
这里只是推荐一下好用的插件,具体的使用方法就不一一详细介绍了. JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用它都可以实现热部署.收费的,破解比较麻烦.不过功 ...
- 手把手带你自定义 Gradle 插件 —— Gradle 系列(2)
请点赞加关注,你的支持对我非常重要,满足下我的虚荣心. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友 ...
- Android 热修复Nuwa的原理及Gradle插件源码解析
现在,热修复的具体实现方案开源的也有很多,原理也大同小异,本篇文章以Nuwa为例,深入剖析. Nuwa的github地址 https://github.com/jasonross/Nuwa 以及用于 ...
- Java开发必装的IntelliJ IDEA插件
IDEA 插件简介 常见的IDEA插件主要有如下几类: 常用工具支持 Java日常开发需要接触到很多常用的工具,为了便于使用,很多工具也有IDEA插件供开发使用,其中大部分已经在IDEA中默认集成了. ...
- Gradle 1.12用户指南翻译——第46章. Java 库发布插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- IntelliJ IDEA 插件 阿里巴巴Java开发手册(Alibaba Java Coding Guidelines)
以前看到过个:Java开发手册(阿里巴巴-公开版),这是个pdf文档,里面描述了一些Java开发的规约,里面确实有很多好用的规约,要是在学校就有机会看看的话,那么,在毕业之后,实际工作中就会少很多坑. ...
随机推荐
- CodeForces - 948C (前缀和+二分)
博客界面的小人搞不好导致无心写博客 题意:tyd非常喜欢玩雪,下雪下了n天,第i天她会堆一堆大小为Vi的雪堆,但因为天气原因,每堆雪会融化Ti,问每天总共融化了多少雪: 直接上代码+注释 1 #inc ...
- 【2020杭电多校】Total Eclipse 并查集+思维
题目链接:Total Eclipse 题意: t组输入,给你一个由n个点,m条边构成的图,每一个点的权值是ai.你每一次可以选择一批联通的点,然后让他们的权值都减去1.问最后把所有点的权值都变成0需要 ...
- 前、中、后序遍历随意两种是否能确定一个二叉树?理由? && 栈和队列的特点和区别
前序和后序不能确定二叉树理由:前序和后序在本质上都是将父节点与子结点进行分离,但并没有指明左子树和右子树的能力,因此得到这两个序列只能明确父子关系,而不能确定一个二叉树. 由二叉树的中序和前序遍历序列 ...
- Codeforces Round #481 (Div. 3) C. Letters (模拟,二分)
题意:有个\(n\)个公寓,每个公寓\(a_{i}\)代表着编号为\(1-a_{i}\)个房间,给你房间号,问它在第几栋公寓的第几个房间. 题解:对每个公寓的房间号记一个前缀和,二分查找属于第几个公寓 ...
- 2019-2020 ACM-ICPC Brazil Subregional Programming Contest Problem A Artwork (并查集)
题意:有一个矩形,有\(k\)个警报器,警报器所在半径\(r\)内不能走,问是否能从左上角走到右下角. 题解:用并查集将所有相交的圆合并,那么不能走的情况如下图所示 所以最后查询判断一下即可. 代码: ...
- Yocto项目介绍及入门 -- 嵌入师工程师必备利器
目录 写在前面 1. Yocto项目是什么 2. Yocto项目有什么用 3. 如何快速上手Yocto项目 4. 带你通过Yocto项目编译一个自定义镜像文件 写在前面 博主目前从事BMC工作,由于公 ...
- 在kubernetes集群里集成Apollo配置中心(3)之交付Apollo-portal至Kubernetes集群
1.执行apollo-portal数据库脚本 apollo-portal数据库脚本链接:https://raw.githubusercontent.com/ctripcorp/apollo/1.5.1 ...
- L3-002. 堆栈【主席树 or 线段树 or 分块】
L3-002. 堆栈 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家都知道"堆栈"是一种"先 ...
- C# Arrays
Arrays 数组是一系列items 的集合,可以进行各种操作,比如sorting等 定义方式: 数据类型[] 数组名; 使用之前需要实例化,这就是实例化了一个含有2个元素的string 数组 还记得 ...
- JavaScript DOM操作之查找元素节点
概要: 编程接口 可通过 JavaScript 对 HTML DOM 进行访问. 所有 HTML 元素被定义为对象,而编程接口则是对象方法和对象属性. 方法是您能够执行的动作(比如添加或修改元素). ...