赞
踩
目录
Ps:如果不是因为某种必须原因,建议学习 Maven 即可,Gradle 的学习成本比 Maven 要高很多...
所需要具备的前置知识:
a)安装之前,确保安装好 Java 环境,版本不能低于 Java 8(这种远古版本就别用了),本文使用 Java 17 .
b)进入 Gradle 官网下载 Gradle 8.5 版本(Gradle 版本兼容性很差,不同版本差异很大,不建议轻易更换),选择以编译好的 二进制 文件即可.
官网下载地址如下:
https://gradle.org/releases/?_gl=1*bycxul*_ga*MTkwMDMxNTMyMS4xNzAzNjkxNjA5*_ga_7W7NC6YNPT*MTcwMzc2MDE2OS4yLjEuMTcwMzc2MTE0OS4zNi4wLjA.
c)下载完后,解压,建议放到 C:/Program Files 目录下
d)配置环境变量:
e)打开命令窗口,输入 gradle -v 查看配置是否生效:
a)打开 cmd 窗口,执行以下命令来初始化项目:
gradle init
b)出现以下内容让我们初始化项目类型,选择 2 应用类型.
c)本文统一使用 Kotlin 语言讲解,选择 4 号:
d)是否生成多个子项目结果. 这里我们先以最简单的单体项目来进行讲解,选择 no 即可:
e)选择编写 gradle 脚本采用的语言,这里使用 Kotlin 语言(也是官方推荐的语言):
f)指定当前项目的名称以及包名,默认是当前目录的名字.
g)选择 Java 版本,这里使用 Java17,输入 17 即可.
h)是否选择使用新特性,选择 no 就可以了(gradle 的兼容性真的很差...),这样就完成了初始化.
Ps:不同版本的 Gradle 对 IDEA 版本同样存在兼容性的问题,推荐使用 IDEA 2023.3 或者更高的版本.
i)使用 IDEA 打开这个项目,打开后会进行初始化,报考 Gradle 当前版本,以及所需要的依赖包和 Kotlin 相关库.
但是我们本地不是已经安装 gradle 了么,为什么又要下载一次?
这是由于 gradle wrapper 的作用. 因为 gradle 的跨版本兼容性很差,所以她指定了当前项目使用的 gradle 版本,让不同开发人员或者 CI/CD 系统都能使用相同的 gradle 版本来构建项目. gradle wrapper 还有另外一个好处,它可以自动下载和使用正确版本的 gradle,无需手动安装或者配置 gradle,使得团队协作更加方便. 后续别人拿到这个项目的时候,不需要再系统中重新部署 gradle 环境.
如果初始化出现以下错误:
说明你之前配置过 gradle ,只需要去 file -> settings 中配置一下以下信息即可
gradle 在创建项目的时候给我们生成了一个主类用来测试:
- class App {
- val greeting: String
- get() {
- return "Hello World!"
- }
- }
-
- fun main() {
- println(App().greeting)
- }
可以看到如下运行结果:
腾讯云做的国内镜像:
https://mirrors.cloud.tencent.com/gradle/
a)解决 gradle 不同版本下载慢的问题:修改当前项目的 gradle/wrapper/gradle-wrapper.properties 文件,位置如下:
修改内容如下:
- distributionBase=GRADLE_USER_HOME
- distributionPath=wrapper/dists
- # 1.默认走如下地址,由于停止了国内的 CDN,下载速度特别慢
- # distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
- # 2.因此,可以使用腾讯云提供的镜像,下载速度极快
- distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.5-bin.zip
- networkTimeout=10000
- validateDistributionUrl=true
- zipStoreBase=GRADLE_USER_HOME
- zipStorePath=wrapper/dists
b)解决依赖包下载慢的问题:使用 阿里云 的镜像网站即可.
- repositories {
- mavenLocal()
- maven {
- setUrl("https://maven.aliyun.com/repository/public")
- }
- mavenCentral()
- }
gradle 的构建项目的命令就是通过前面我们讲到 gradle 初始化的项目中包含两个构建脚本实现的,分别是 gradle 和 gradle.bat,前者是 mac 系统适用,后者是 win 系统适用.
a)首先来看一下 gradle 支持的所有任务,可以通过以下命令来执行.
./gradlew.bat task
task 中包含了大量的命令操作,如下:
- PS D:\codeRepositories\Gitee\java\gradle_test> .\gradlew.bat task
- Downloading https://mirrors.cloud.tencent.com/gradle/gradle-8.5-bin.zip
- ............10%.............20%............30%.............40%.............50%............60%.............70%.............80%............90%.............100%
- Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
- Directory 'D:\JDK8' (Windows Registry) used for java installations does not exist
- Directory 'D:\JDK8' (Windows Registry) used for java installations does not exist
- <==
- > Task :tasks
-
- ------------------------------------------------------------
- Tasks runnable from root project 'gradle_test'
- ------------------------------------------------------------
-
- Application tasks
- -----------------
- run - Runs this project as a JVM application
-
- Build tasks
- -----------
- assemble - Assembles the outputs of this project.
- build - Assembles and tests this project.
- buildDependents - Assembles and tests this project and all projects that depend on it.
- buildKotlinToolingMetadata - Build metadata json file containing information about the used Kotlin tooling
- buildNeeded - Assembles and tests this project and all projects it depends on.
- classes - Assembles main classes.
- clean - Deletes the build directory.
- jar - Assembles a jar archive containing the classes of the 'main' feature.
- kotlinSourcesJar - Assembles a jar archive containing the sources of target 'kotlin'.
- testClasses - Assembles test classes.
-
- Build Setup tasks
- -----------------
- init - Initializes a new Gradle build.
- wrapper - Generates Gradle wrapper files.
-
- Distribution tasks
- ------------------
- assembleDist - Assembles the main distributions
- distTar - Bundles the project as a distribution.
- distZip - Bundles the project as a distribution.
- installDist - Installs the project as a distribution as-is.
-
- Documentation tasks
- -------------------
- javadoc - Generates Javadoc API documentation for the 'main' feature.
-
- Help tasks
- ----------
- buildEnvironment - Displays all buildscript dependencies declared in root project 'gradle_test'.
- dependencies - Displays all dependencies declared in root project 'gradle_test'.
- dependencyInsight - Displays the insight into a specific dependency in root project 'gradle_test'.
- help - Displays a help message.
- javaToolchains - Displays the detected java toolchains.
- kotlinDslAccessorsReport - Prints the Kotlin code for accessing the currently available project extensions and conventions.
- outgoingVariants - Displays the outgoing variants of root project 'gradle_test'.
- projects - Displays the sub-projects of root project 'gradle_test'.
- properties - Displays the properties of root project 'gradle_test'.
- resolvableConfigurations - Displays the configurations that can be resolved in root project 'gradle_test'.
- tasks - Displays the tasks runnable from root project 'gradle_test' (some of the displayed tasks may belong to subprojects).
-
- Verification tasks
- ------------------
- check - Runs all checks.
- checkKotlinGradlePluginConfigurationErrors - Checks that Kotlin Gradle Plugin hasn't reported project configuration errors, failing otherwise. This task always runs before compileKotlin* or similar tasks.
- test - Runs the test suite.
- To see all tasks and more detail, run gradlew tasks --all
- To see more detail about a task, run gradlew help --task <task>
- BUILD SUCCESSFUL in 34s
- 1 actionable task: 1 executed
- PS D:\codeRepositories\Gitee\java\gradle_test>
这里我们主要来看一下下图中的命令:
b)task 中的第一个 run 命令会自动编译和运行项目,拿出来单独执行,效果如下:
c)如果将来我们修改了项目的内容,需要重新编译,就要先进行 clean 进行清理
d)编写号 Java 项目之后,第一步就是编译成 class 文件
./gradlew classes
此时就会在 app 目录下生成一个 build 目录,此目录中就存在的是编译之后的文件了.
e)有些时候我们不想执行测试,只想构建整个项目,可以添加参数跳过:
./gradlew build -x test
f)但是这样敲命令太烦人了,IDEA 中已经包含了 Gradle 插件,可以直接使用:
gradle 项目构建流程:
a)settings.gradle.kts 是整个 Gradle 项目的入口,用来定义所有子项目,让他们参与到构件中.
因此:
b)settings.gradle.kts 文件中,gradle 会默认实例化一个 Settings 对象,所有项目声明都是通过她来实现的.
settings.rootProject.name = "demo1"
也可以省略掉 settings.
rootProject.name = "demo1"
c)Settings 对象
包含如下常用属性:
属性 | 描述 |
---|---|
buildCache | 项目构建所用缓存配置。 |
plugins | 用于设置的插件。 |
rootDir | 项目构建的根目录,根目录是整个项目目录最外层。 |
rootProject | 构建的根项目。 |
settings | 返回设置对象。 |
包含以下方法可以调用:
方法 | 描述 |
---|---|
include() | 将指定名称的项目添加到构建列表中。 |
includeBuild() | 添加指定路径上的其他Gradle项目到构建列表中。 |
d)一般 Gradle 设置文件按照如下方式编写:
- // 当前项目的名称
- rootProject.name = "demo1"
-
- //每个子模块的名称(没有子模块可以不写)
- include("aaa")
- include("bbb")
- include("ccc")
e)配置文件中的内容,本质是对 Gradle API 方法的调用,结合 Kotlin 中 {...} 语法(Kotlin 中称为 lambda)
在每一个 build.gradle.kts 文件中,Gradle 都会为其创建一个 Project 实例对象,可以直接使用.
- group = "com.cyk"
- version = "1.0-SNAPSHOT"
当然,也可以省略 project
- group = "com.cyk"
- version = "1.0-SNAPSHOT"
此对象中,还包含以下常见属性
属性 | 类型 | 描述 |
---|---|---|
name | String | 项目目录的名称。 |
path | String | 该项目的完全限定名称。 |
description | String | 该项目的描述。 |
layout | ProjectLayout | 通过此对象来访问项目中的关键位置。 |
另外常用属性还有一些是以 lambda 的形式来编写的,往下走~
- plugins {
- kotlin("jvm") version "1.9.21"
- application
- }
-
- //也可以写成以下形式
- plugins {
- id("org.jetbrains.kotlin.jvm") version "1.9.21"
- id("application")
- }
kotlin 表示整个项目的所使用的插件,而 application 是由官方内置的插件,可以不用指定 version ,而 kotlin 未被官方内置,所以需要手动指定 version ,Gradle 才能在仓库中找到她.
另外还可以对这些插件进行一些配置,例如编译的目标版本是 jdk17
- tasks.withType<KotlinCompile> {
- kotlinOptions.jvmTarget = "17"
- }
使用 application 插件,它包含 java 插件的全部功能,同样支持编译和打包,并且支持生成可执行的应用程序.
- plugins {
- kotlin("jvm") version "1.9.21"
- application //引入 application 插件
- }
-
- application {
- //配置主类(build.classes.kotlin 目录下的绝对路径)
- //注意: Main.kt 编译后生成的字节码文件名为 MainKt
- //指导生成可执行程序执行的入口
- mainClass.set("com.cyk.kt.MainKt")
- }
通过 build 命令构建以后,可以看到 application 插件生效了,生成了如下文件:
这里我们只需要解压缩,就能看到 application 插件生成的可执行程序:
进入 bin 目录
双击运行 demo1.bat 即可运行(建议可以先打开终端,再打开该程序,否则程序一闪而过)
也可以直接通过 idea 提供的插件,直接运行可执行程序,如下
初始化 Gradle 项目之后,默认是选择 Maven 中央仓库,下载速度极慢(慢到即使有梯子也不行,因为 Gradle 关闭了国内的 cdn)
- repositories {
- mavenCentral()
- }
为了解决上述问题,我们一般都是优先使用本地仓库,本地仓库没有,再去阿里云仓库(速度快),最后在考虑中央仓库.
- repositories {
- mavenLocal() //本地仓库
- maven {
- setUrl("https://maven.aliyun.com/repository/public") //阿里云仓库(第三方仓库)
- }
- mavenCentral() //中央仓库
- }
a)这里可以使用以下函数导入依赖:
b)函数的参数就是一个字符串,就是我们依赖的组、名称、版本号:
org.junit:junit-bom:5.9.1
对应的组为 org.junit
,依赖名称为:junit-bom
,版本号为:5.9.1
c)使用 implementation 添加依赖的步骤:
- dependencies {
- testImplementation(kotlin("test"))
- implementation("org.springframework.boot:spring-boot-starter:2.6.7")
- }
另外,还可以分开编写 组、名称、版本,提高可读性:
- dependencies {
- testImplementation(kotlin("test"))
- implementation("org.springframework.boot", "spring-boot-starter","2.6.7")
- }
在使用依赖时,我们可能需要排除某些不需要的依赖,或者与其他依赖冲突,我们也可以对依赖进行排除操作:
- dependencies {
- testImplementation(kotlin("test"))
- implementation("org.springframework.boot", "spring-boot-starter","2.6.7") {
- //以 lambda 的形式排除依赖
- exclude("org.springframework.boot", "spring-boot-starter-logging")
- }
- }
a)Gradle 上一个工作由多个任务来完成,比如构建、编译、清理... 这些任务都由插件提供.
不引入任何插件的情况下,只有一些内置任务:
b)引入 Kotlin / Java 插件之后,就出现了 编译、构建、打包... 等任务.
- plugins {
- kotlin("jvm") version "1.9.21"
- application //引入 application 插件
- }
c)如果觉得插件提供的任务不够,还可以在 build.gradle.kts 中自定义添加.
注册任务需要使用 register 或 create 函数来完成,例如如下:
- tasks.register("hi~") {//第一个参数是任务名称,第二个参数是 lambda 编写的具体任务
- //任务包含一个完整的操作列表,需要传入对应的 Action 到队列中,这样便会依次执行
- doFirst { //向队列首部插入 Action
- println("自定义任务开始!")
- }
- doLast { //向队列尾部插入 Action
- println("自定义任务结束!")
- }
- }
刷新之后就出现了我们自定义的任务
效果如下:
我们甚至还可以配置此任务所属的组,以及描述信息:
d)另外我们还可以指定自定义任务的前置任务,例如但我们点击自定义任务时,先执行 build 命令,如下:
- tasks.register("hi~") {//第一个参数是任务名称,第二个参数是 lambda 编写的具体任务
- group = "build"
- description = "自定义任务~"
- //指定前置任务为 build
- dependsOn(tasks.build)
- doFirst { //向队列首部插入 Action
- println("task start~")
- }
- doLast { //向队列尾部插入 Action
- println("task end~")
- }
- }
手动执行自定义任务后,自动先触发 build 命令
e)当然,返回来也可以,例如我们执行 build 命令时,会先自动执行自定义任务:
f)在 gradle 中,所有任务都是 Task 子类,除了上述所写方式(register),我们也可以自己创建 Task 子类,用来编写自定义任务类型:
- //继承 DefaultTask 来创建一个自定义的 HiTask 类
- //这个类要么是可继承,要么是 open,要么是抽象类
- open class HiTask: DefaultTask() {
- private var name: String = ""
-
- fun user(name: String) {
- this.name = name
- }
-
- @TaskAction //添加@TaskAction 注解来声明此函数为任务
- fun hi() {
- println("${name}: 最帅!")
- }
-
- }
-
- //使用 register 来指明我们自定义的任务类型
- tasks.register<HiTask>("hi") {
- this.user("cyk") //此时 this 就是 HiTask
- }
效果如下:
g)Gradle 还提供了一些内置任务类型,例如复制任务:
- tasks.register<Copy>("hello") { //这里使用Copy类型
- from("build/classes") //使用from和into设置复制的目录和目标位置
- into("test")
- dependsOn(tasks.build) //依赖一下build
- }
有时候我们希望在 Gradle 整个声明周期中不同时期执行一些操作,就可以使用钩子函数(类似 Vue 钩子).
例如,我们可以利用这个特性来统计某一个任务的耗时:
我们可以将自己的 Gradle 项目发布到 Maven 仓库中,这里以发布到本地仓库为例:
- publishing {
- publications {
- //Maven 坐标信息
- create<MavenPublication>("library") {
- groupId = "com.cyk"
- artifactId = "demo1"
- version = "0.0.1"
- from(components["java"]) // jar 包发布
- }
- }
-
- //指定发布仓库
- repositories {
- mavenLocal() //发布到本地 Maven 仓库
- }
- }
执行 publish 命令即可发布到本地仓库(注意每次发布都更新一下版本号,防止仓库中优先执行缓存)
此时在 .m2 中就可以看到我们发布的项目了
这里使用 IDEA 创建 Kotlin SpringBoot 项目就不用多说了... (注意选择 Gradle Kotlin DSL 即可)
这里来看一下项目自动生成的 build.gradle.kts 文件:
- import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
- plugins {
- id("org.springframework.boot") version "3.1.8" //SpringBoot 插件
- id("io.spring.dependency-management") version "1.1.4" //Spring 依赖管理插件
- kotlin("jvm") version "1.8.22"
- kotlin("plugin.spring") version "1.8.22"
- }
-
- group = "com.cyk"
- version = "0.0.1-SNAPSHOT"
-
- java {
- sourceCompatibility = JavaVersion.VERSION_17 //配置 Java 源代码编译版本
- }
-
- // Maven 仓库配置
- repositories {
- maven {
- setUrl("https://maven.aliyun.com/repository/public")
- }
- mavenLocal()
- mavenCentral()
- }
-
- // 依赖配置
- dependencies {
- implementation("org.springframework.boot:spring-boot-starter-web")
- implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
- implementation("org.jetbrains.kotlin:kotlin-reflect")
- testImplementation("org.springframework.boot:spring-boot-starter-test")
- }
-
- //对 Kotlin 编译任务进行配置(告诉 Gradle 中所有类型为 KotlinCompile 任务,然后进行配置)
- tasks.withType<KotlinCompile> {
- //指定编译参数
- kotlinOptions {
- freeCompilerArgs += "-Xjsr305=strict" //JSR-305 是一组用于 Java 编程语言的注解,用于提供更多的静态代码分析信息
- jvmTarget = "17" //生成 JVM 字节码的目标版本
- }
- }
-
- //让 Gradle 再执行测试时使用 Junit 平台
- tasks.withType<Test> {
- useJUnitPlatform()
- }
一般分布式项目,我们都会在一个项目中包含多个模块,不同模块负责不同功能.
这里我们来看一下,一般多模块的结构如下:
- xxx-parent
- |
- ├── user-service
- │ ...
- │ └── build.gradle.kts
- ├── album-service
- │ ...
- │ └── build.gradle.kts
- └── settings.gradle.kts
settings.gradle.kts 用于全局配置,而 build.gradle.kts 用来对具体的模块进行配置.
a)新建一个简单的 project
b)接着,就可以删除掉不需要的目录,比如: src 目录、build.gradle.kts、gradlew 等.
c)右键 gradle-parent ,然后创建子模块.
Ps:这里语言选择没有 Kotlin,也可以先使用 Java 创建
d)创建完后,可以看到最外层的 settings.gradle.kts 文件自动为我们添加了模块.
Ps:此时我们在根项目中执行任何命令,都会对全部子模块生效
e)由于创建模块时不支持指定 Kotlin 语言,因此我们先指定的 Java 语言.
这里就可以将 java 目录重命名为 kotlin
此时我们只需要随便创建一个 Kotlin 文件
他就会提示我们没有配置 Kotlin,点击配置后,IDEA 就会自动为我们配置 Kotlin 相关插件.
选择版本即可
a)有时候,我们需要在 子模块a 中引入 子模块b,我们就可以在项目中通过 implementation(project(":xxx")) 来引入其他子模块,如下:
b)gradle 项目通过 implementation 进行依赖传递存在这样一个问题:
例如有三个模块:a、b(依赖 a)、c(依赖b)
按照这个传递关系来说 c 是可以拿到 a 中的东西(Maven 是支持的),但实际上:
也就是说通过 implementation 进行依赖传递,最多只能传递一层.
Ps:gradle 为什么要这样设定呢?因为这样编译时只需要处理一层,速度就会非常快,大部分情况下非常推荐使用 implementation 进行依赖导入.
但如果一定要是实现依赖传递的效果,也不是不行,只是需要使用另一个插件提供的方法来导入:
有些时候,我可能每次创建一个子模块都要在 build.gradle.kts 中配置很多相同的配置,例如 仓库地址、插件.......
因此我们可以直接在项目根目录下创建一个 build.gradle.kts 文件来编写统一配置:
- plugins {
- kotlin("jvm") version "1.8.22" apply false
- }
-
- subprojects { //subprojects表示对所有的子项目生效
- apply(plugin = "kotlin")
- //定义插件需要使用apply来完成,plugin{}在这里不行
-
- repositories { //定义自定义仓库地址
- maven {
- setUrl("https://maven.aliyun.com/repository/public")
- }
- mavenLocal()
- mavenCentral()
- }
- }
这样我们在子项目中就不用再配置相同的配置了.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。