1. 引言

Gradle 是一款广受欢迎的构建工具,其高度可定制的构建流程备受开发者青睐。本文将展示如何创建自定义 Gradle 插件,帮助我们在标准配置之外进一步扩展构建能力。

2. 插件源码位置

插件代码可以存放在不同位置,各有优劣:

2.1. 构建脚本内

直接将插件源码写在构建脚本中:

// build.gradle
class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.task('hello') {
            doLast { println 'Hello Gradle!' }
        }
    }
}
apply plugin: GreetingPlugin

优点:自动编译并包含插件
缺点:插件无法在构建脚本外复用

2.2. buildSrc 目录

将代码放在 buildSrc/src/main/java 目录:

project/
├── buildSrc/
│   └── src/main/java/
│       └── GreetingPlugin.java
└── build.gradle

优点:可在同一项目的多个构建脚本间共享
缺点:无法跨项目使用

2.3. 独立项目

创建单独的插件项目:

greeting-plugin/
├── src/main/java/
│   └── GreetingPlugin.java
└── build.gradle

优点:完全可复用
⚠️ 注意:需打包成 JAR 并添加到目标项目

3. 第一个插件

所有 Gradle 插件必须实现 org.gradle.api.Plugin 接口:

public class GreetingPlugin implements Plugin<Project> {
    @Override
    public void apply(Project project) {
        project.task("hello")
          .doLast(task -> System.out.println("Hello Gradle!"));
    }
}

在构建脚本中应用:

apply plugin: GreetingPlugin

执行 gradle hello 即可看到输出。

4. 插件配置

通过扩展对象实现外部配置:

public class GreetingPluginExtension {
    private String greeter = "Baeldung";
    private String message = "Message from the plugin!";
    // 标准getter/setter
}

在插件中注册扩展:

@Override
public void apply(Project project) {
    GreetingPluginExtension extension = project.getExtensions()
      .create("greeting", GreetingPluginExtension.class);

    project.task("hello")
      .doLast(task -> {
          System.out.println("Hello, " + extension.getGreeter());
          System.out.println("I have a message for You: " + extension.getMessage());
      });
}

在构建脚本中配置:

greeting {
    greeter = "Stranger"
    message = "Message from the build script"
}

5. 独立插件项目

5.1. 项目设置

添加 Gradle API 依赖:

dependencies {
    compile gradleApi()
}

Maven 配置示例:

<dependencies>
    <dependency>
        <groupId>org.gradle</groupId>
        <artifactId>gradle-tooling-api</artifactId>
        <version>3.0</version>
    </dependency>
    <dependency>
        <groupId>org.gradle</groupId>
        <artifactId>gradle-core</artifactId>
        <version>3.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
<repositories>
    <repository>
        <id>repo.gradle.org</id>
        <url>https://repo.gradle.org/gradle/libs-releases-local/</url>
    </repository>
</repositories>

5.2. 插件注册

创建属性文件 src/main/resources/META-INF/gradle-plugins/org.baeldung.greeting.properties

implementation-class=org.gradle.GreetingPlugin

5.3. 插件 ID 规范

ID 必须符合以下规则:

  • 只能包含字母、数字、.-
  • 必须包含至少一个 . 分隔域名和插件名
  • 禁止使用 org.gradlecom.gradleware 命名空间
  • 不能以 . 开头或结尾
  • 不能有连续的 . 字符
  • 建议使用小写反向域名格式

5.4. 发布插件

两种发布方式:

  1. 发布到仓库:如 Maven 或 Ivy
  2. Gradle 插件门户:供社区使用(详见官方文档

5.5. Java Gradle 开发插件

使用 java-gradle-plugin 插件简化开发:

plugins {
    id 'java-gradle-plugin'
}

✅ 自动添加 gradleApi() 依赖
✅ 执行插件元数据验证

6. 测试插件

使用 ProjectBuilder 进行 JUnit 测试:

@Test
public void greetingTest(){
    Project project = ProjectBuilder.builder().build();
    project.getPluginManager().apply("com.baeldung.greeting");
 
    assertTrue(project.getPluginManager()
      .hasPlugin("com.baeldung.greeting"));
 
    assertNotNull(project.getTasks().getByName("hello"));
}

7. 总结

本文介绍了 Gradle 插件开发的基础知识。更深入的插件开发技巧可参考Gradle 官方文档。所有示例代码可在GitHub获取。


原始标题:Writing Custom Gradle Plugins | Baeldung

» 下一篇: Java Weekly, 第206期