Gradle 是一个开源的自动化构建工具,其核心是基于 Java 实现,可以把它看成一个轻量级的 Java 应用,可以使用 Groovy 或 Kotlin 来编写脚本,简化了开发时对项目构建要做的配置,使用更加灵活和强大。
配置文件
build.gradle
该文件是项目构建文件,每个工程都有一个build.gradle文件,它在配置阶段执行,并创建相应工程的Project对象,执行的代码可以直接调用该对象提供的方法或者属性。
settings.gradle
该文件是在初始化阶段执行,创建Setting对象,在执行脚本时可调用此对象方法,它决定了哪些模块参与构建过程。
基本概念
项目:每个 build.gradle 都是一个项目对象,每一次 gradle 构建都至少包含一个项目,每个项目中都有各自的任务。
任务/task:任务定义在构建脚本中,包含一系列的动作,类似于一个方法,比如 clean 任务:
1
2
3
task clean(type: Delete) {
delete rootProject.buildDir
}
声明周期
如上图所示,共分为三个阶段:
1. 初始化
Gradle支持单项目和多项目构建。在初始化阶段,执行settings.gradle脚本,Gradle读取include信息,并 确定哪些项目将参与构建,并为每个工程创建一个与之对应的Project 对象,最终形成一个项目层次结构。
2. 配置
配置阶段,执行每个工程的 build.gradle 文件,完成Project的配置,并且构造出Task任务依赖的一个有向无环图DAG,以供执行阶段按照依赖顺序执行,并对任务做一些初始化配置。
3. 执行
运行阶段,Gradle 根据配置阶段创建和配置的要执行的任务子集,执行任务。
Task
语法:
1
2
3
4
5
6
7
8
9
10
11
task <任务名称> {
// 代码块
doFirst {
// 执行
}
doLast {
}
}
上面代码中,定义在task中的代码块只是设置了任务的配置,在配置阶段执行,那么想要在执行阶段添加动作action,就可以在doFirst和doLast方法中添加。
依赖
task A(dependsOn:[B]){ .. } 表示任务 A 依赖于任务 B,那么 B 执行在 A 之前。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
task A{
println "test A"
doLast{
println "test A-doLast"
}
}
//这里表示任务B依赖任务A,在A执行后才会执行B
task B(dependsOn:[A]){
println "test B"
doLast{
println "test B-doLast"
}
}
// 执行./gradlew B
> Configure project :app
test A
test B
> Task :app:A
test A-doLast
> Task :app:B
test B-doLast
插件
自定义 Gradle 插件有三种方式:
- 构建脚本
可以直接在构建脚本中包含插件的源代码。这样做的好处是插件可以自动编译并包含在构建脚本的类路径中,而不需要您做任何事情。然而,插件只能在定义它的构建脚本之内可见,不能在其他脚本中复用插件。
- buildSrc
可以将插件的源代码放在rootProjectDir/buildSrc/src/main/java
目录(或rootProjectDir/buildSrc/src/main/groovy
或rootProjectDir/buildSrc/src/main/kotlin
中,具体取决于你使用的语言)。 Gradle将负责编译插件,并使其在构建脚本的类路径中可用。 该插件对整个项目里的每个构建脚本都是可见的, 但是,它在项目外部不可见,因此不能其他项目中复用该插件。
- 独立项目
可以为插件创建一个单独的项目,将项目打包成一个JAR包,然后可以在多个项目中复用。
实践
执行gradle init命令,按照下面步骤一步一步选择配置,最终创建完项目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Starting a Gradle Daemon (subsequent builds will be faster)
Select type of project to generate:
1: basic
2: application
3: library
4: Gradle plugin
Enter selection (default: basic) [1..4] 4
Select implementation language:
1: Groovy
2: Java
3: Kotlin
Enter selection (default: Java) [1..3] 1
Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2] 1
Project name (default: gradle_plugin): com.yuxingxin.plugintest
Source package (default: com.yuxingxin.plugintest):
> Task :init
Get more help with your project: https://docs.gradle.org/7.2/userguide/custom_plugins.html
BUILD SUCCESSFUL in 35s
2 actionable tasks: 2 executed
紧接着创建一个名为Greeting的任务,目的是向该插件的项目注册一个这样的任务,它做的事情就是在doLast时候打印一句话。
1
2
3
4
5
6
7
8
9
10
public class HelloPlugin implements Plugin<Project> {
public void apply(Project project) {
// Register a task
project.tasks.register("greeting") {
doLast {
println("Hello from plugin 'com.yuxingxin.plugintest.greeting'")
}
}
}
}
发布该插件需要借助Maven Publish Plugin插件,首先在build.gradle中应用:
1
2
3
4
plugins {
...
id 'maven-publish'
}
然后定义插件的发布信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
publishing {
publications {
// 这里的 hello 可以任意命名
hello(MavenPublication) {
// 插件的组ID,建议设置为插件的包名
groupId = 'com.yuxingxin.plugintest'
// 插件ID
artifactId = 'greeting'
version = '1.0.0'
// 组件类型,我们的插件其实就是Java组件
from components.java
}
}
// 不指定repositories会默认发布在.m2/repository/目录下
repositories {
maven {
// 这里发布到自己项目,$rootDir 表示你项目的根目录
url = "$rootDir/repo"
}
}
}
然后就可以接入自己的项目使用了。