认识 Gradle
一、Gradle
Gradle 与 Maven 的区别可以看这篇 文章。
日常作为简单的依赖管理使用哪个都是没有问题的。有句话说的好:高端玩家选择自定义设置,普通玩家选择默认配置 :smile: 高级功能不一定使用。
不过另一方面,Gradle 社区更新、更换 API 很勤快,也许上个版本还在用的 API,等更新版本后就幸运的看到了中国红!所以大家对 Maven 的版本要求一点儿也不严格,但是对于 Gradle,emmmm,这个得看你们的脚本用了什么 API。
本文示例全部使用 kts 的写法(Gradle Version >= 7),也就是 kotlin 式的语法,体验比 Groovy 棒多啦!推荐可以看一下 B 站霍老师的的视频:
{% video bilibili:BV1Kf4y1p7zq %}
gradle 默认的 url 分发地址,大概在 2023 年 9 月份开始,官网的下载速度就不行了,之前飞快,现在只能找找国内镜像。 可以前往 腾讯云 或者 阿里云 下载对应的版本。
二、配置
Gradle 的配置分为两种,一种是本地安装的方式,就和本地安装的 Maven 一样;另一种则是直接配置一个环境变量。这 两种方式二选一 就好。
第一种:设置 GRADLE_USER_HOME 环境变量,该变量不需要扔到 Path 里,只需要配置一个存储空间较大的路径,后面在使用 IDE 的时候,如果自动下载,那么所有版本的 gradle 安装包、依赖都会下载到此目录。结构如下(使用后就有了):
├── caches # 依赖包
├── daemon # 守护进程运行日志以及注册的二进制文件(wrapper/)
├── init.gradle.kts # 初始化脚本
├── jdks #
├── kotlin-profile # 空的,看名字应该是 Kotlin 的支持吧
├── native # 本机 dll 文件
├── notifications # 不知道干嘛的
└── wrapper # 下载的 Gradle 二进制文件
第二种:本地安装😉在本地安装的目录中添加以下文件。
allprojects {
repositories {
maven("https://maven.aliyun.com/repository/public")
mavenCentral()
// Google 仓库
google()
}
}
镜像源脚本路径
若本地安装了 Gradle,上面的脚本就放在本地安装的目录中;若本地未安装,放在配置的环境变量的目录中;如果前面两项都不满足,那么放在默认的路径:~/.gradle 。
若本地安装且配置了环境变量,命令行才可以使用 gradle;未安装只能在项目路径下使用 ./gradlew 命令(wrapper 会自动调用守护进程)。
关于环境变量请参考 Gradle 官网。
GRADLE_HOME自己本机安装的 Gradle 目录;GRADLE_USER_HOME:自定义下载依赖的存放的路径,包括wrapper/gradle/下定义的各种版本的 Gradle 及其下载的依赖。在GRADLE_USER_HOME变量缺失的时候,默认的位置为~/.gradle/。
Gradle 是如何查找并使用本地的配置呢?
# Gradle 查找下载配置的顺序 * 代表可以为任意名称
~/.gradle/init.gradle
~/.gradle/init.d/*.gradle
GRADLE_HOME/init.d/*.gradle
GRADLE_USER_HOME/init.gradle
GRADLE_USER_HOME/init.d/*.gradle
# Gradle 查找依赖的顺序
# M2_HOME 是 Maven 的安装路径环境变量
~/.m2/settings.xml
M2_HOME/conf/settings.xml
~/.m2/repository
三、几个重要文件
单模块很简单,本文就不演示了。这里使用多模块项目作为一个小示例:
|-- Project
|-- sub-project-1
|-- src
|-- build.gradle.kts
|-- sub-project-2
|-- src
|-- build.gradle.kts
|-- settings.gradle.kts
|-- gradle.properties
1. settings.gradle.kts
// 项目根文件夹名称
rootProject.name = "Project"
// 包含的子模块,下面两种写法二选一
// 可以交叉使用,但是浪子更推荐第二种写法
// 冒号表示相对路径;
// 也支持省略冒号的方式,若省略则被解释为相对于 settings.gradle.kts 文件所在目录的路径
// 方式一:
include(":sub-project-1", ":sub-project-1", ":module3", ":module4")
// 方式二:
include(":sub-project-1")
include(":sub-project-2")
// 还可以定制其它插件、管理依赖、版本等等,欲知详情,使用 idea 建立一个 quarkus 项目看看!
2. build.gradle.kts
该文件是我们最常见、常改的文件。
// 项目使用插件
plugins {
}
// 基本信息
group = "com.code"
version = "1.0-SNAPSHOT"
// Java 版本
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
// 对所有项目生效的配置
allprojects {
// 应用于所有项目的插件
apply {
plugin("插件名称")
}
repositories {
// 本地仓库
mavenLocal()
// 腾讯云仓库
maven("https://mirrors.cloud.tencent.com/nexus/repository/maven-public/")
// 默认不允许使用 http 下载,如果项目中需要从 http 下载依赖,打开下面的设置
// maven {
// url = uri("http://mirrors.cloud.tencent.com/nexus/repository/maven-public/")
// isAllowInsecureProtocol = true
// }
}
// 所有项目引入依赖
dependencies {
testImplementation "org.springframework.boot:spring-boot-starter-test"
}
// other task and config
}
// 只对子项目生效的配置
subprojects {
// 和 allprojects 的配置相同
}
// 设置编译器的字符集,以便能够正确地处理文件中的 Unicode 字符。
// 添加 JVM 参数
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
}
3. gradle.properties
该文件可以声明 gradle 使用的环境变量,进而覆盖 gradle 的默认配置。也可以在这里定义、维护版本号,总之这里的内容可以在被上面两个文件引用。
# 启用守护进程
org.gradle.daemon=true
# 使用并行构建
org.gradle.parallel=true
# 开启构建缓存
org.gradle.caching=true
四、Gradle scope
在Gradle中,有几种不同的依赖范围,它们定义了依赖在不同阶段的行为和可见性。以下是一些常见的依赖范围:
-
api:
- 在新的Android插件和一些非Android项目中,推荐使用
api替代compile。 api范围的依赖在编译和运行时都是可用的,并且会被传递到依赖此模块的其他模块。- 这意味着,当你在某个模块中使用
api来声明一个依赖时,这个依赖会同时被编译和打包到该模块的输出,并且任何依赖于这个模块的其他模块也将能够访问到这个依赖。
- 在新的Android插件和一些非Android项目中,推荐使用
-
implementation:
implementation范围的依赖在编译和运行时对当前模块是可用的,但在编译依赖此模块的其他模块时不可见。- 这意味着,如果你在一个模块中使用
implementation依赖了一个库,那么其他依赖这个模块的模块需要自己再次声明对这个库的依赖。
-
runtimeOnly(或
runtime):runtimeOnly范围的依赖只在运行时是必需的,编译时不需要。- 这种依赖通常用于那些只需要在运行时加载的库,如JDBC驱动、日志框架的配置文件等。
-
testImplementation:
testImplementation范围的依赖只在编译和运行测试代码时需要,不会影响主代码的编译和运行。- 这种依赖通常用于测试框架和相关的库。
-
testRuntimeOnly:
testRuntimeOnly范围的依赖只在运行测试时需要,编译测试代码时不需要。- 这种依赖通常用于那些只在测试环境中使用的资源或库。
只有使用
java-library才可以使用 api,java-library插件是 java 插件的升级,它支持 java 插件的所有功能,并引入了额外的新功能。
五、Version Catalog
Gradle 7.x 引入了 version catalog 功能预览,gradle 8 默认启用(读取项目目录下的 gradle/libs.versions.toml),对于 Gradle 多模块需要依赖共享的项目非常好用。version-catalog 方式引入的依赖也是惰性的,即在文件中声明的依赖如果没有项目引入,则不会进行下载。
个人不是很喜欢 extra 和 buildSrc 的方式,当然,如果使用 kts 可以在文件里直接 val xxxVersion = "version" 更香。
在项目根目录的 gradle/ 目录中创建 libs.versions.toml 文件管理所有依赖,子项目中按需引入。该文件分为以下几个部分(里面的内容只是例子):
[versions]
# 版本管理
springBoot = "3.3.3"
springDenpendencyManagement = "1.1.7"
[libraries]
# 依赖管理,有两种编写方式
# 第一种
spring-boot = { group = "org.springframework.boot", name = "spring-boot", version.ref = "springBoot" }
spring-boot-starter-aop = { group = "org.springframework.boot", name = "spring-boot-starter-aop", version.ref = "springBoot" }
# 第二种
spring-boot-starter-security = { module = "org.springframework.boot:spring-boot-starter-security", version.ref = "springBoot" }
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "springBoot" }
[bundles]
# 依赖分组/打包
spring = [
"spring-boot",
"spring-boot-starter-aop",
"spring-boot-starter-security",
"spring-boot-starter-web"
]
[plugins]
# 插件管理
spring-boot = { id = "org.springframework.boot", version.ref = "springBoot" }
spring-dependency-management = { id = "io.spring.dependency-management", version.ref = "springDenpendencyManagement" }
子模块使用时非常简单:
// 使用 libs.versions.toml 定义的插件
plugins {
alias(libs.plugins.xxx)
}
// 使用 libs.versions.toml 定义的依赖
dependencies {
// 单独引入一个依赖
// implementation(libs.spring.boot)
// 引入依赖组,包含组里的所有依赖
// 即引入了 "spring-boot", "spring-boot-starter-aop", "spring-boot-starter-security", "spring-boot-starter-web"
implementation(libs.bundles.spring)
}
libs.versions.toml是 Gradle 默认查找并读取的文件名称,也可以使用其它名称(譬如开发和生产使用不同类型、不同版本的依赖项,可能会定义多个文件),不过需要在settings.gradle.kts中做一些配置,让 Gradle 可以读取,配置方式自行查阅 官方文档。- 版本定义上面使用了
version.ref的方式,也可以使用version直接写版本字符串,例如spring-boot = { module = "org.springframework.boot:spring-boot", version = "3.3.3" }。- 在
libs.versions.toml中定义名称使用-分割(spring-boot),但在使用时需要使用.分割(libs.spring.boot)。
六、附:CLI 命令
# 查看帮助
./gradlew -h
./gradlew --status
# 停止 gradle daemon 服务
./gradlew --stop
# 刷新依赖关系的状态。
./gradlew -U 或者 ./gradlew --refresh-dependencies
./gradlew -d, --debug
./gradlew -s, --stacktrace
# 查询依赖
./gradlew dependencies
# 输出依赖到文件中
./gradlew dependencies --console=dependency-tree.txt

说些什么吧!