Gradle构建工具

Gradle构建工具

身边有学习安卓的大佬强烈推荐我学习了解下Gradle这款构建工具,说是将会是未来的主流,所以来此学习并记录下。

货比三家

Ant Maven Gradle
公司 Apache Apache Google
语言 xml xml Groovy
构建性能 速度最快 速度最低 中间
依赖管理 ivy管理 GAV管理 GNV管理
插件管理 简单 复杂 简单
侧重 小型项目构建 项目包管理 大型项目构建
流行程度(2022) 中(未来趋势)

总结:各有各的优缺点,虽然gradle结合了ant和maven的优点,但是现在的兼容性还比较查

下载源配置

在gradle安转目录的init.d文件夹下新建一个init.gradle文件
init.gradle

allprojects {
  repositories {
    mavenLocal()
    maven {
      name "Alibaba"; 
      url "https://maven.aliyun.com/repository/public"
    }
    maven {
      name "Spring"; 
      url "https://repo.spring.io/libs-milestone/"
    }
    mavenCentral()
  }
  
  buildscript {
    repositories {
      maven {
        name "Alibaba";
        url 'https://maven.aliyun.com/repository/public'
      }
      maven {
        name "Spring";
        url 'https://repo.spring.io/plugins-release/'
      }
      maven {
        name "M2";
        url 'https://plugins.gradle.org/m2/'
      }
    }
  }
}

说明(从上至下搜索)

  • mavenLocal() 从本地maven找,需配置M2_HOME环境变量,变量值为maven地址
  • Alibaba 阿里下载源
  • mavenCentral() maven中央仓库
    tip: 配置源参考阿里云官方

Gradle目录构结

目录 功能
/build 封装编译后的文件、测试报告
/gradle/wrapper/ 封装包装器文件夹
/src 速度最快|
/gradlew mac/linux端包装器启动脚本
/gradlew.bat windows端包装器启动脚本
/build.gradle 构建脚本(类似maven的pom)
/setting.gradle 设置项目信息

文件结构与maven极其相似,都是基于约定大于配置(Convention over configuration)的设定

**Gradle中的依赖(Dependencies)

依赖方式

  • 直接依赖:依赖本地的某个jar包,具体可通过 文件集合、文件树的方式指定
  • 项目依赖:依赖某个project
  • 本地jar依赖:依赖的类型 依赖的组名 依赖的名称 依赖的版本号
dependencies {
  //直接依赖
  implementation 'org.apache.logging.log4j:log4j:2.17.2'
  // 完整写法
  implementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.1'
  //依赖当前项目下的某个模块[子工程]
  implementation project(':subject01')
  //直接依赖本地的某个jar文件
  implementation files('libs/foo.jar', 'libs/bar.jar')
  //配置某文件夹作为依赖项
  implementation fileTree(dir: 'libs', include: ['*.jar'])

}

tips: 若项目中版本号是’+'/'latest.integration’表示下载最新版本, 最好是不用这种动态版本声明,容易出现版本问题

依赖下载

执行gradle build会去配置的依赖仓库下载jar包

依赖类型

类似maven中的scope

类型 作用
compileOnly 由java插件提供,曾短暂的叫provided,后续版本已经改成了compileOnly,适用于编译期需要而不需要打包的情况
runtimeOnly 由 java 插件提供,只在运行期有效,编译时不需要,比如 mysql 驱动包。,取代老版本中被移除的runtime
implementation 由 java 插件提供,针对源码[src/main 目录] ,在编译、运行时都有效,取代老版本中被移除的 compile
testCompileOnly 由 java 插件提供,用于编译测试的依赖项,运行时不需要
testRuntimeOnly 由 java 插件提供,只在测试运行时需要,而不是在测试编译时需要,取代老版本中被移除的 testRuntime
testImplementation 由 java 插件提供,针对测试代码[src/test 目录] 取代老版本中被移除的 testCompile
providedCompile war 插件提供支持,编译、测试阶段代码需要依赖此类 jar 包,而运行阶段容器已经提供了相应的支持,所以无需将这些文件打入到 war 包中了;例如 servlet-api.jar、jsp-api.jar
compile 编译范围依赖在所有的 classpath 中可用,同时它们也会被打包。在 gradle 7.0 已经移除
runtime runtime 依赖在运行和测试系统的时候需要,在编译的时候不需要,比如 mysql 驱动包。在 gradle 7.0 已经移除
api java-library 插件提供支持,这些依赖项可以传递性地导出给使用者,用于编译时和运行时。取代老版本中被移除的 compile
compileOnlyApi java-library 插件提供支持,在声明模块和使用者在编译时需要的依赖项,但在运行时不需要。

官方:
各个依赖范围的关系和说明
依赖范围升级和移除
API和implemention区别
执行 java 命令时都使用了哪些依赖范围的依赖

tips:

  1. java 插件提供的功能,java-library 插件都提供。
  2. api与implementation的区别
    1. 编译时:api能实现底层传递,底层变,全部变,编译速度慢;implementation不能进行依赖传递,底层变,不用全部变,编译快
    2. 应用:api适用于多模块的场景,一般场景使用implementation
    3. 运行时所有模块的class都需要编译,api和implementation差不多

依赖冲突及解决方案

依赖冲突是指 “在编译过程中, 如果存在某个依赖的多个版本, 构建系统应该选择哪个进行构建的问题”

Project A
Project B
Project C
log4j 1.4.2
log4j 2.2.4
  • gradle默认会使用新版本。 如上图所示,gradle引入的1.4.2版本会被替换成2.2.4版本
  • 可使用exclude,来移除依赖,不允许依赖传递,强制使用指定版本
        implementation('org.hibernate:hibernate-core:3.6.3.Final'){
         //下面三种都行
         exclude group: 'org.slf4j'
         //exclude module: 'sl4j-api'
         //exclude group: 'org.slf4j', module: 'sl4j-api'
     }
    
  • 配置不允许传递依赖(不建议):transitive(false)
      implementation('org.hibernate:hibernate-core:3.6.3.Final'){
        //不允许依赖传递,一般不用
        transitive(false)
      }
    
  • 强制使用指定版本的依赖
    //强制使用某个版本!!【官方建议使用这种方式】
    implementation('org.slf4j:slf4j-api:1.4.0!!')
    //这种效果和上面那种一样,强制指定某个版本
    implementation('org.slf4j:slf4j-api:1.4.0'){
      version{
        strictly("1.4.0")
      }
    }
    

任务执行

官方文档

常用命令

命令 作用
gradle build 构建项目:编译、测试、打包
gradle run 运行一个自定义服务,需要application插件支持,并且指定了主启动类(mainClassName=xxx)才能运行
gradle clean 清空build目录
gradle init 初始化gradle项目使用
gradle wrapper 生成wrapper文件夹
gradle wrapper --gradle-version=x.x 升级 wrapper 版本号
gradle wrapper --gradle-version 5.2.1 --distribution-type all 关联源码用
gradle classes 编译业务代码和配置文件
gradle test 编译测试代码,生成测试报告|
gradle build -x test 跳过测试构建
gradle [taskName] :执行自定义任务

项目报告相关任务

命令 作用
gradle projects 列出所选项目及子项目列表,以层次结构的形式显示
gradle tasks 列出所选项目【当前 project,不包含父、子】的已分配给任务组的那些任务
gradle tasks --all 列出所选项目的所有任务
gradle tasks --group=“build setup” 列出所选项目中指定分组中的任务
gradle help --task someTask 显示某个任务的详细信息
gradle dependencies 查看整个项目的依赖信息,以依赖树的方式显示
gradle properties 列出所选项目的属性列表

选项

调试常用选项
选项 作用
-h,–help 查看帮助信息
-v, --version 打印 Gradle、 Groovy、 Ant、 JVM 和操作系统版本信息
-S, --full-stacktrace 打印出所有异常的完整(非常详细)堆栈跟踪信息
-s,–stacktrace 打印出用户异常的堆栈跟踪(例如编译错误)
-Dorg.gradle.daemon.debug=true 调试 Gradle 守护进程
-Dorg.gradle.debug=true 调试 Gradle 客户端(非 daemon)进程
-Dorg.gradle.debug.port=(port number) 指定启用调试时要侦听的端口号。默认值为 5005
性能选项

tips: 在gradle.properties中指定这些选项中的许多选项,因此不需要命令行标志

选项 作用
–build-cache, --no-build-cache 尝试重用先前版本的输出。默认关闭(off)
–max-workers 设置 Gradle 可以使用的 woker 数。默认值是处理器数
-parallel, --no-parallel 并行执行项目。有关此选项的限制,请参阅并行项目执行
守护进程选项
选项 作用
–daemon, --no-daemon 使用 Gradle 守护进程运行构建。默认是 on
–foreground 在前台进程中启动 Gradle 守护进程。
-Dorg.gradle.daemon.idletimeout=(number of milliseconds) Gradle Daemon 将在这个空闲时间的毫秒数之后停止自己。默认值为 10800000(3 小时)。默认设置为关闭(off)
日志选项
选项 作用
-Dorg.gradle.logging.level=(quiet,warn,lifecycle,info,debug) 通过 Gradle 属性设置日志记录级别
-q, --quiet 只能记录错误信息
-w, --warn 设置日志级别为warn
-i, --info 将日志级别设置为info
-d, --debug 登录调试模式(包括正常的堆栈跟踪)
其他
选项 作用
-x -x 等价于: --exclude-task : 常见 gradle -x test clean build
–rerun-tasks 强制执行任务,忽略 up-to-date ,常见 gradle build --rerun-tasks
–continue 忽略前面失败的任务,继续执行,而不是在遇到第一个失败时立即停止执行。每个遇到的故障都将在构建结束时报告,常见:gradle build --continue。
gradle init --type pom 将 maven 项目转换为 gradle 项目(根目录执行)

拓展

  • gradle 任务名是缩写: 任务名支持驼峰式命名风格的任务名缩写,如:connectTask 简写为:cT,执行任务 gradle cT。
  • 前面提到的 Gradle 指令本质:一个个的 task【任务】, Gradle 中所有操作都是基于任务完成的

Wrapper包装器

GradlerWrapper为解决没有gradle的环境下使用gradle项目的问题。只需要使用构建项目时生成的gradlew/gradlew.bat,需注意的是使用gradlew的命令需要依赖于jdk

  • 运行的依赖包在gradle/wrapper下
  • Gradle的使用方式和gradlew是一样的
  • 可使用gradle wrapper指定参数控制wrapper版本(升级项目的gradle),
    参数 说明
    –gradle-version 用于指定使用的Gradle版本
    –gradle-distribution-url 用于指定下载Gradle发行的url地址

Groovy

概述
  • 基于JVM的敏捷开发语言
  • 是一种成熟的面向对象编程语言,既可以用于面向对象,也可以用作纯粹的脚本语言
  • 适合与spring的动态语言一起使用,设计时充分考虑了Java的集成
基本语法
  • 可以面向对象(写个类),也可以不面向对象(不写类)
  • 可以混合类的定义和脚本的定义,但是定义的类名不能与文件名重名
  • 使用def定义变量、方法,不建议使用具体的数据类型
  • 可省略",",以换行符作为结束
  • 支持顺序、分支、循环结构
  • 支持算数、关系、位、赋值运算符
  • 基本数据类型也是对象
  • 字符串分为单引号(作为字符串常量,没有运算能力)、双引号(可引用变量${},有运算能力)、三引号(模板字符串,支持换行)
  • 变量、属性、方法、闭包的参数可不写,使用的时候决定他的类型
  • 如果一个groovy文件包含脚本信息,这个类编译的时候会默认继承Script类,这个类的名称为文件名,脚本内容被打包至run方法里,有main函数调用。若不包含脚本信息,groovy是个对象,则会实现GroovyObject接口。
对象
  • 默认类、方法、属性是用public修饰的
  • 属性属性操作
    • 赋值
      • 对象.属性 = xxx
      • 对象.set属性(xxx),不用自己定义get,set方法
      • 具名构造器
    • 读取
      • 对象.属性
      • 对象.get属性()
      • 对象[“属性”]
    • 对象的赋值、读取的本质都是getter、setter方法完成
  • 方法
    • 声明时返回值可省略,return关键字也可省略,默认返回最后一行的值
    • 调用时,()可省略

Gradle测试

test {
    enabled(true) // build时执行同时进行测试,生成测试报告
    useJUnitPlatform() //支持Junit5测试
//    include("space/rexhub/bj/test/*") // 测试指定包
    exclude("space/rexhub/bj/test/*") // 不测试指定包
}

Gradle项目周期

  • Initialization
    • Init Script: 执行init.gradle文件,包含仓库信息、仓库用户名密码等一些全局属性配置
    • Setting Script: 执行setting.gradle文件,构建参与项目的所有模块,setting.gradle包含项目信息
  • Configuration:按照层级结构执行各个项目中的build.gradle文件,并更具层级关系创建一个Task有向无环图
  • execution:执行各个task节点的任务

settings文件

  • 作用:初始化阶段确定哪些工程需要加入到项目构建中,为构建项目工程树做准备。
  • 工程树:类似maven的module
  • 位置:必须在根工程下
  • 名字:必须为setting.gradle
  • 内容:定义当前项目以及子项目的项目名称
  • 对应实例:与package org.gradle.api.initialization.Settings一一对应
  • 使用:使用相对路径【:】引入子工程。子工程必须在setting中配置了才会被gradle识别

Task

项目实质上是Task 对象的集合。一个 Task 表示一个逻辑上较为独立的执行过程,比如编译 Java 源代码,拷贝文件,打包 Jar 文件,甚至可以是执行一个系统命令。另外,一个 Task 可以读取和设置 Project 的 Property 以完成特定的操作。

简单使用

  1. 在build.gradle中
def map = Collections.singletonMap("action", {println "task one..."})

//task(map,  "task1", {})
task (map, "task1") {
    // 任务的配置段,在任务的配置阶段进行
    println "这是最简单的任务"
    // 任务的行为:在任务执行阶段执行
    doFirst{
        println "task1 do first"
    }
    //
    doLast{
        println "task1 do last"
    }
}
task1.doFirst {
    println "task1 do first(outer)"
}
task1.doLast {
    println "task1 do first(outer)"
}
  1. 命令行执行gralde -i task1
  2. 输出
> Configure
....
这是最简单的任务
....
> Task :task1
....
task1 do first(outer)
task1 do first
task one...
task1 do last
task1 do first(outer)

任务定义方式

  1. task(): task(‘A’, {…})、task ‘A’ {…}、task(‘A’){…}
  2. tasks对象的create()/register(): tasks.create(“E”){…}、tasks.register(“…”)
    1. register: 延迟创建,只有task被调用的时候才会创建
      tips: 可使用defaultTasks()定义任务(在没有指定其他任务时执行的默认任务)

任务的属性

属性 描述 默认值
type 基于一个存在的Task来创建,类似继承 DefaultTask
overwrite 是否替换存在的Task,这个和type配合起来用 false
dependsOn 配置任务的依赖 []
action 添加到任务中的一个Action或者一个闭包 null
description 配置任务的描述 null
group 配置任务的分组 null
enable 任务是否开启 true
timeout 任务执行的时间 (tasks never time out)
onlyIf 任务断言, 如:myClean.onlyIf(!project.hasProperties(“clean”)),执行:gradle myClean -Pclean 才会调用myClean的方法 null

Tasks的方法

方法 描述 用例
findByName 根据任务名查找 tasks.findByName(“myClean”).doFirst({…})
findByPath 根据任务路径查找 tasks.findByName(“:myClean”).doFirst({…})
addRule 处理任务不存在异常 tasks.addRule(“cleanRule”){String taskName -> task(taskName){println “任务不存在”} }

原理分析

无论是定义任务自身的 action,还是添加的 doLast、doFirst 方法,其实底层都被放入到一个 Action 的 List中了,最初这个 action List 是空的,当我们设置了 action【任务自身的行为】,它先将 action 添加到列表中,此时列表中只有一个 action,后续执行 doFirst 的时候 doFirst 在 action 前面添加,执行 doLast 的时候 doLast 在 action 后面添加。doFirst永远添加在 actions List 的第一位,保证添加的 Action 在现有的 action List 元素的最前面;doLast 永远都是在 action List末尾添加,保证其添加的 Action 在现有的 action List 元素的最后面。一个往前面添加,一个往后面添加,最后这个 actionList 就按顺序形成了 doFirst、doSelf、doLast 三部分的 Actions,就达到 doFirst、doSelf、doLast 三部分的 Actions 顺序执行的目的

任务的依赖方式:dependsOn

  1. 参数方式依赖
    实例:

    task A {
      doLast{
        println "TaskA..."
      }
    }
    task B {
      doLast{
        print "TaskB..."
      }
    }
    // 参数方式依赖:dependsOn后面用冒号
    task 'C' (dependsOn: ['A', 'B']){
      doLast {
        println "TaskC..."
      }
    }
    

    输出:

    
    > Task :A
    TaskA...
    
    > Task :B
    TaskB...
    > Task :C
    TaskC...
    
    
  2. 内部依赖
    实例:

    task 'A'{...}
    task 'B'{...}
    // 参数方式依赖
    task 'C'{
      // 内部依赖:dependsOn后面=号
      dependsOn=['A', 'B']
      doLast {
        println "TaskC."
      }
    }
    

    输出同上

  3. 外部依赖
    实例:

    // 外部依赖:可变参数可加可不加
    task 'A'{...}
    task 'B'{...}
    // 参数方式依赖
    task 'C'{...}
    C dependsOn('B', 'A')
    

    输出同上

tips:

  • 依赖支持跨项目依赖
  • 当一个 Task 依赖多个 Task 的时候,被依赖的 Task 之间如果没有依赖关系,那么它们的执行顺序是随机的,并无影响
  • 重复依赖的任务只会执行一次

任务类型。官方(更多点这)

常见任务类型 该类型任务的作用
Delete 删除文件或目录
Copy 将文件复制到目标目录中。此任务还可以在复制时重命名和筛选文件
CreateStartScripts 创建启动脚本
Exec 执行命令行进程
GenerateMavenPom 生成 Maven 模块描述符(POM)文件。
GradleBuild 执行 Gradle 构建
Jar 组装 JAR 归档文件
JavaCompile 编译 Java 源文件
Javadoc 为 Java 类生成 HTML API 文档
PublishToMavenRepository 将 MavenPublication 发布到 mavenartifactrepostal
Tar 组装 TAR 存档文件
Test 执行 JUnit (3.8.x、4.x 或 5.x)或 TestNG 测试
Upload 将 Configuration 的构件上传到一组存储库
War 组装 WAR 档案
Zip 组装 ZIP 归档文件。默认是压缩 ZIP 的内容
自定义类型的Task

继承DefaultTask

class CustomTask extends DefaultTask {
//@TaskAction表示Task本身要执行的方法
@TaskAction
  def doSelf(){
    println "Task自身在执行的in doSelf"
  }
}
def myTask=task MyDefinitionTask (type: CustomTask)
myTask.doFirst(){
  println "task 执行之前 执行的 doFirst方法"
} 
myTask.doLast(){
  println "task 执行之后 执行的 doLast方法"
}

指定Task执行顺序。官方

  1. dependsOn 强依赖方式
  2. 通过Task输入输出
  3. 通过API指定执行顺序

动态分配功能。

  • 可循环创建任务,可以使用它在运行时动态地向任务添加依赖项
    4.times { counter ->
        tasks.register("task$counter") {
            doLast {
                println "I'm task number $counter"
            }
        }
    }
    tasks.named('task0') { dependsOn('task2', 'task3') }
    

插件

作用

  • 添加任务【task】到项目中,从而帮助完成测试、编译、打包等
  • 添加依赖配置到项目中。
  • 向项目中拓展新的扩展属性、方法等
  • 对项目进行一些约定,如应用 Java 插件后,约定 src/main/java 目录是我们的源代码存在位置,编译时编译这个目录下的 Java 源代码文件

分类

gradle插件
脚本插件
二进制插件(对象插件)
内部插件
第三方插件
自定义插件
apply方式
plugins DSL方式
apply(map具名参数)
apply闭包
传统使用方式
plugins DSL
1. 先引入依赖
2. 通过apply应用
构建过程中默认执行
脚本插件
  1. 编写脚本文件
    version.gradle
    ext{
      company = "Rexhub"
      cfgs = ["compileSdkVersion":"JavaVersion.VERSION_1_S"]
      spring = [
        version: '5.0.0'
      ]
    }
    
  2. 引入
    task versionTask{
      doLast{
        println "公司名称为:${company},JDK版本是${cfgs.compileSdkVersion},版本号是${spring.version}"
      }
    }
    

执行脚本结果:

> Task :versionTask
公司名称为:Rexhub,JDK版本是JavaVersion.VERSION_1_S,版本号是5.0.0

tips: 脚本文件可以是本地的,也可以是网络上的

内部插件

二进制插件(对象插件)就是实现了 org.gradle.api.Plugin 接口的插件,每个 Java Gradle 插件都有一个 plugin id。核心插件(gradle官方)

  • apply方式引入
    • apply(map具名参数)
      //plugin: '插件id/插件全类名/插件简类名'
      apply plugin: 'java' //map具名参数方式
      
    • apply(闭包)
      apply{
        //plugin '插件id/插件全类名/插件简类名'
        plugin 'java'
      }
      
  • plugins DSL
    plugins {
      id 'java'
      id 'application'
    }
    

第三方插件

  1. 传统方式
    1. 引入依赖
      buildscript {
        ext {
          springBootVersion = "2.3.3.RELEASE"
        } 
        repositories {
          mavenLocal()
          maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
          jcenter()
        } 
        // 此处先引入插件
        dependencies {
          classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
      }
      
      tips:
      • 但是如果是第三方插件已经被托管在 https://plugins.gradle.org/ 网站上,就可以不用在buildscript里配置classpath依赖了
      • buildscript{}需要放在gradle文件最前面
    2. 通过apply应用
      apply plugin: 'org.springframework.boot' //社区插件,需要事先引入,不必写版本号
      
  2. plugins DSL
    plugins {
      id 'org.springframework.boot' version '2.4.1'
    }
    

自定义插件

项目内简单定义方式(这种方式一般不用)

官方文档

interface GreetingPluginExtension {
  Property<String> getMessage()
  Property<String> getGreeter()
} 
class GreetingPlugin implements Plugin<Project> {
  void apply(Project project) {
  def extension = project.extensions.create('greeting', GreetingPluginExtension)
    project.task('hello') {
      doLast {
        println "${extension.message.get()} from ${extension.greeter.get()}"
      }
    }
  }
}
apply plugin: GreetingPlugin
// Configure the extension using a DSL block
greeting {
  message = 'Hi'
  greeter = 'Gradle'
}
buildSrc方式

buildSrc 是 Gradle 默认的插件目录,编译 Gradle 的时候会自动识别这个目录,将其中的代码编译为插件

项目内方式
  1. 创建名为buildSrc的java module,在setting.gradle中移除included modules信息。只保留build.gradle和src/main目录
  2. 修改gradle中的内容
    apply plugin: 'groovy' //必须
    apply plugin: 'maven-publish'
    dependencies {
        implementation gradleApi() //必须
        implementation localGroovy() //必须
    }
    repositories {
        google()
        jcenter()
        mavenCentral() //必须
    }
    //把项目入口设置为src/main/groovy
    sourceSets {
        main {
            groovy {
                srcDir 'src/main/groovy'
            }
        }
    }
    
  3. 在src中创建入口目录,如:space.rexhub
  4. 在入口目录中创建插件,如:Text.groovy
    package space.rexhub
    
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    
    /**
    * Description: Text插件
    * @author Rex
    * @date 2022-11-06 15:26
    */
    class Text implements Plugin<Project>{
        @Override
        void apply(Project project) {
            project.task("rexhub"){
                doLast {
                    println "自定义插件使用"
                }
            }
    
        }
    }
    
  5. 创建main/resources/META-INF/gradle-plugins目录,在这个目录下创建properties,文件名为插件id
  6. 在properties文件中指名插件的全类名
     implementation-class=space.rexhub.Text
    

tips: 这种方式可以跨模块调用,但仅限于本工程

将项目上传至maven的方式

基于上述步骤改进

  1. 将buildSrc复制一份并重命名,如:rexhub,在setting.gradle引入
  2. 修改rexhub中的build.gradle文件,发布到仓库中
    apply plugin: 'groovy' //必须
    apply plugin: 'maven-publish'
    dependencies {
        implementation gradleApi() //必须
        implementation localGroovy() //必须
    }
    repositories {
        google()
        jcenter()
        mavenCentral() //必须
    }
    //把项目入口设置为src/main/groovy
    sourceSets {
        main {
            groovy {
                srcDir 'src/main/groovy'
            }
        }
    }
    publishing {
        publications {
            myLibrary(MavenPublication) {
                groupId = 'space.rexhub.plugin' //指定GAV坐标信息
                artifactId = 'library'
                version = '1.1'
                from components.java//发布jar包
    //from components.web///引入war插件,发布war包
            }
        }
        repositories {
            maven { url "$rootDir/lib/release" }
            //发布项目到私服中
            // maven {
            // name = 'myRepo' //name属性可选,表示仓库名称,url必填
            // //发布地址:可以是本地仓库或者maven私服
            // //url = layout.buildDirectory.dir("repo")
            // //url='http://my.org/repo'
            // // change URLs to point to your repos, e.g. http://my.org/repo
            // //认证信息:用户名和密码
            // credentials {
            // username = 'joe'
            // password = 'secret'
            // }
            // }
        }
    }
    
  3. 执行 publish 指令,发布到根 project 或者 maven 私服仓库。
  4. 使用:在项目级 build.gradle 文件中将插件添加到 classpath
    buildscript {
        repositories {
            maven { url "$rootDir/lib/release" }
        }
        dependencies {
            classpath "space.rexhub.plugin:library:1.1"
        }
    }
    plugins{
        id 'java'
        id 'space.rexhub.plugin'
    }
    
    
  5. 执行 gradle build 指令就会在控制台看到自定义插件的输出,说明自定义插件就已经生效了

你可能感兴趣的:(Gradle,gradle)