开发效率优化之自动化构建系统Gradle(二)下篇(1)

  • build.gradle 中创建的插件将被自动编译并包含在 classpath 中,使用时无需在构建脚本内指定 classpath

缺点:

  • 此插件仅在当前构建脚本中有效,对外部文件不可见,无法在当前构建脚本以外的其他地方复用此插件

示例

1. 创建 BuildInDemo 目录

mkdir BuildInDemo

2. 在 BuildInDemo 目录内中新建 build.gradle 文件

cd BuildInDemo

touch build.gradle

使用 tree 命令查看创建后的目录结构,如下所示

BuildInDemo

.

└── build.gradle

0 directories, 1 file

3. 在 BuildInDemo/build.gradle 内创建并应用 Gradle 插件,代码如下

// 1. 创建插件 BuildInPlugin

class BuildInPlugin implements Plugin {

// 2. 应用插件时执行此函数

@Override void apply(Project target) {

println(“hello form build-in plugin”)

}

}

//3. 应用插件

apply plugin: BuildInPlugin

// 2. 应用插件时执行此函数

@Override void apply(Project target) {

println(“hello form build-in plugin”)

}

}

//3. 应用插件

apply plugin: BuildInPlugin

4. 构建此 build.gradle 文件

gradle build

Gradle 构建时将执行 build.gradle 中的代码,当执行到 apply plugin: BuildInPlugin 时,将会调用 BuildInPlugin 的实例方法 apply(Project p)。因此在构建过程中,可以看到如下输出,其中第 2 行即为上一步自定义插件中打印的内容,表明插件应用成功

Configure project :

hello form build-in plugin

Task :buildEnvironment


Root project


classpath

No dependencies

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 0s

1 actionable task: 1 executed

buildSrc 模块方式

rootProject/buildSrc 文件夹是 Gradle 的预留目录,用来存放当前项目私有 Gradle 插件的源代码与构建脚本

优点:

  • 项目构建时,Gradle 会自动编译项目目录下的 buildSrc 文件夹下的构建脚本和源码,并将其添加到项目构建脚本的 classpath 中,因此在使用 buildSrc 中创建的插件时,无需再手动指定 classpath

  • buildSrc 文件夹中构建脚本和 Gradle 插件同一项目均可见,因此同一项目中的其他模块也可以使用 buildSrc 中创建的插件

缺点:

  • 此处创建的插件对外部项目不可见,无法在其他项目中复用

示例

1. 创建 PluginBuildSrcDemo 项目模块

创建 PluginBuildSrcDemo 目录,并在该目录下创建 build.gradle 文件

mkdir PluginBuildSrcDemo && cd PluginBuildSrcDemo && touch build.gradle

2. 创建 buildSrc 子模块
2.1 在 PluginBuildSrcDemo 目录下创建 buildSrc 目录

mkdir buildSrc

2.2 在 PluginBuildSrcDemo/buildSrc 目录下创建 buildSrc 子模块的构建脚本文件 build.gradle

cd buildSrc

touch build.gradle

PluginBuildSrcDemo/buildSrc/build.gradle 的内容如下

// 使用 plugins 块语法应用插件

plugins {

// 应用 kotlin 插件

id ‘org.jetbrains.kotlin.jvm’ version ‘1.3.50’

}

dependencies {

// 仅在编译时使用 Grdale-API 依赖

compileOnly gradleApi()

// 在插件源码中添加 kotlin 标准库依赖

implementation ‘org.jetbrains.kotlin:kotlin-stdlib’

}

2.3 创建 buildSrc 模块的源码目录

cd PluginBuildSrcDemo/buildSrc

mkdir -p /src/main/kotlin/com/example/plugin

2.4 创建插件文件 PluginBuildSrc.kt

cd PluginBuildSrcDemo/buildSrc/src/main/kotlin/com/example/plugin

touch PluginBuildSrc.kt

PluginBuildSrc.kt 的代码如下

package com.example.plugin

import org.gradle.api.Plugin

import org.gradle.api.Project

class PluginBuildSrc : Plugin {

override fun apply(target: Project) {

println(“hello from buildSrc plugin”)

}

}

2.5 声明 Gradle 插件的 ID 与实现类

此步骤是可选的:若使用插件 ID 形式应用自定义插件,则必须进行此步骤;若使用插件实现类的形式应用自定义插件,则可跳过此步骤。

完成此步骤的方式有两种,任选其一即可

方式 1. META-INF 方式

创建 PluginBuildSrcDemo/buildSrc/src/main/resources/META-INF/gradle-plugins 目录

cd PluginBuildSrcDemo/buildSrc

mkdir -p src/main/resources/META-INF/gradle-plugins

gradle-plugins 目录下创建 com.example.plugin.properties 属性文件,红色部分表示插件的 ID

cd src/main/resources/META-INF/gradle-plugins

touch com.example.plugin.properties

属性文件的内容如下,表示插件 ID 为 com.example.plugin 的插件所对应的实现类为 com.example.plugin.PluginBuildSrc

implementations-class=com.example.plugin.PluginBuildSrc

方式 2. java-gradle-plugin 插件方式

java-gradle-plugin 是一个用于开发 Gradle 插件的辅助插件,它内置了很多辅助功能:

  1. 为宿主模块添加 gradlePlugin 配置块,可在此处配置插件的 ID 和实现类

  2. 为宿主模块添加 complile gradleApi() 依赖

  3. etc…

此处我们主要使用 gradlePlugin 配置块代替 META-INF 目录下的属性文件。java-gradle-plugin 的使用方式非常简单,只需在 PluginBuildSrcDemo/buildSrc/build.gradle 构建脚本文件中简单配置即可,如下所示。

plugins {

id ‘org.jetbrains.kotlin.jvm’ version ‘1.3.50’

  • //1. 应用 java-gradle-plugin 插件

  • id 'java-gradle-plugin' 
    

}

dependencies {

  • compileOnly gradleApi() // java-gradle-plugin 插件已为宿主添加 gradleApi 依赖,此行可移除 
    

implementation ‘org.jetbrains.kotlin:kotlin-stdlib’

}

  • //2. 添加 gradlePlugin 配置块信息

  • gradlePlugin {

  • plugins{
    
  •     // 此处的 tag 可以为任意名称
    
  •     tag1{
    
  •         id = 'com.example.plugin.buildsrc' //自定义插件的 ID
    
  •         implementationClass  = 'com.example.plugin.PluginBuildSrc' //自定义插件的实现类
    
  •     }
    
  • }
    
  • }

此时在 PluginBuildSrcDemo 目录下使用 tree 命令,可以看到当前的目录结构如下

PluginBuildSrcDemo

.

├── build.gradle

├── buildSrc

│ ├── build.gradle

│ └── src

│ └── main

│ └── kotlin

│ └── com

│ └── example

│ └── plugin

│ └── PluginBuildSrc.kt

7 directories, 3 files

3. 在 PruginBuildSrcDemo 项目模块中应用 buildSrc 中声明的 Gradle 插件

PluginBuildSrcDemo/build.gradle 构建脚本文件中添加如下代码

//apply plugin: ‘插件 ID’

apply plugin: ‘com.example.plugin’

//apply plugin: 实现类

//apply plugin: com.example.plugin.PluginBuildSrc

应用插件时,指定插件 ID 或指定插件的实现类都可以,但指定插件 ID 的形式更为简短及灵活,在实际开发中也更为常见。

PluginBuildSrcDemo 目录下执行 gradle build 命令进行构建,可看到如下输出

Configure project :

hello from buildSrc plugin

Task :buildEnvironment


Root project


classpath

No dependencies

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 3s

1 actionable task: 1 executed

其中第 2 行是我们在 buildSrc 模块中定义的 Gradle 插件所打印日志,表明 buildSrc 模块 中的自定义插件在根项目中已生效。

4. 创建 SubModule 子模块

buildSrc 模块中定义的插件可以在同一项目的任意模块的构建脚本中使用,接下来便演示在 SubModule 子模块中的应用。

4.1 创建 SubModule 目录与构建脚本

// 1. 在 PluginBuildSrcDemo 目录下创建 SubModule 目录

cd PluginBuildSrcDemo && mkdir SubModule

// 2. 在 SubModule 目录下新建 gradle 构建脚本

cd SubModule

touch build.gralde

PluginBuildSrcDemo/SubModule/build.gradle 的内容如下

apply plugin: ‘com.example.plugin’

4.2 将 SubModule 模块关联到 PluginBuildSrcDemo 项目中

PluginBuildSrcDemo 目录下新建 settings.gradle 文件,内容如下

// 将SubModule 子模块添加到 PluginBuildSrcDemo 项目模块中

include ‘:SubModule’

此时在 PluginBuildSrcDemo 目录下使用 tree 命令,可以看到项目当前的目录结构如下

PluginBuildSrcDemo

.

├── SubModule

│ └── build.gradle

├── build.gradle

├── buildSrc

│ ├── build.gradle

│ └── src

│ └── main

│ └── kotlin

│ └── com

│ └── example

│ └── plugin

│ └── PluginBuildSrc.kt

└── settings.gradle

5. 在 SubModule 模块执行构建命令

cd PluginBuildSrcDemo/SubModule

gradle build

得到如下输出

Configure project :SubModule

hello from buildSrc plugin

Task :SubModule:buildEnvironment


Project :SubModule


classpath

No dependencies

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 0s

1 actionable task: 1 executed

独立项目方式

采用 buildSrc 模块方式时,Gradle 会妥善处理 buildSrc 模块的构建脚本与源码,并将其添加到当前项目的 classpath 中。但 buildSrc 方式的插件只能在项目内共享与复用,若要在其他项目中使用该插件,还需要再进行下列操作

  • 将插件发布到 maven 仓库(任意仓库)

  • 在需要应用该插件的构建脚本中的 repository 部分添加该插件所在的 maven 仓库

  • 在需要应用该插件的构建脚本中的 classpath 部分添加该插件对应的 maven 坐标 (group : id : version)

因为是在其他项目中使用该项目 buildSrc 模块 中的自定义 Gradle 插件,所以 Gradle 的 buildSrc 保留目录优势不再。如果将模块名由 buildSrc 修改为其他名称,则可将其称为独立的 Gradle 插件模块。

在本小节中,我们主要学习 gradle 插件的发布与使用。

1. 创建 gradle 插件项目

buildSrc 方式相同,先创建构建脚本与自定义插件类

mkdir StandaloneDemo

cd StandaloneDemo

touch build.gradle

mkdir src/main/kotlin/com/example/plugin

touch src/main/kotlin/com/example/plugin/StandalonePlugin.kt

StandaloneDemo/build.gradle 的内容如下

plugins {

id ‘org.jetbrains.kotlin.jvm’ version ‘1.3.50’

id ‘java-gradle-plugin’

}

gradlePlugin{

plugins{

sometag{

id = ‘com.example.plugin’

implementationClass = ‘com.example.plugin.StandalonePlugin’

}

}

}

StandaloneDemo/src/main/kotlin/com/example/plugin/StandalonePlugin.kt 的内容如下

package com.example.plugin

import org.gradle.api.Plugin

import org.gradle.api.Project

class StandalonePlugin : Plugin {

override fun apply(target: Project) {

println(“hello from standalone plugin”)

}

}

2. 将 gradle 插件发布到 maven 仓库
2.1 在 StandaloneDemo/build.gradle 文件中配置发布信息

使用 maven-publish 插件将自定义插件发布到本地 maven 仓库中,如下所示

plugins {

id ‘org.jetbrains.kotlin.jvm’ version ‘1.3.50’

id ‘java-gradle-plugin’

  • //1. 应用 maven-publish 插件

  • id ‘maven-publish’

}

gradlePlugin{

plugins{

sometag{

id = ‘com.example.plugin’

implementationClass = ‘com.example.plugin.StandalonePlugin’

}

}

}

+//2. 设置发布相关配置

+publishing {

  • publications {

  •    //3. 将插件发布到 maven 仓库
    
  •    maven(MavenPublication) {
    
  •   				//4. 设置插件的 maven 坐标
    
  •        groupId 'com.example'//组织 ID
    
  •        artifactId 'plugin'  //制品 ID
    
  •        version 'snapshot'   //制品版本
    
  •        from components.kotlin
    
  •    }
    
  • }

  • //5. 设置发布仓库

  • repositories {

  •   // 6. 发布到本地 maven 仓库 
    
  •   mavenLocal()
    
  • }

+}

2.2 使用 publishMavenPublicationToMavenLocal 任务将插件发布到本地仓库

cd StandaloneDemo

gradle publishMavenPublicationToMavenLocal

执行以上命令后,gradle 会把 StandaloneDemo 中的代码编译打包后发布到本地 maven 仓库中,本地 maven 仓库通常存放于当前用户目录下,具体路径为

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一起互勉~
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  •        artifactId 'plugin'  //制品 ID
    
  •        version 'snapshot'   //制品版本
    
  •        from components.kotlin
    
  •    }
    
  • }

  • //5. 设置发布仓库

  • repositories {

  •   // 6. 发布到本地 maven 仓库 
    
  •   mavenLocal()
    
  • }

+}

2.2 使用 publishMavenPublicationToMavenLocal 任务将插件发布到本地仓库

cd StandaloneDemo

gradle publishMavenPublicationToMavenLocal

执行以上命令后,gradle 会把 StandaloneDemo 中的代码编译打包后发布到本地 maven 仓库中,本地 maven 仓库通常存放于当前用户目录下,具体路径为

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

[外链图片转存中…(img-pgnr3rbk-1715263157167)]

[外链图片转存中…(img-rnnC30Cy-1715263157168)]

一起互勉~
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值