【2024】Gradle安装配置以及基于Kotlin 进行详细使用

目录💻

一、介绍

在java的项目开发过程中我们会使用到一些依赖管理的构建工具、目前常用的主要有Maven和Gradle两种;Maven不用多说,基本上学java的基本上都会用到,毕竟是现在使用最多的,也是使用的比较久的了,但maven由于使用的是XML进行配置,相对比较繁琐,可读性也比较差;而且构建的数据较慢,不支持增量构建;小项目还好,当比较大型的项目时,就会比较影响。所以Apache重新孵化出了一个新的项目,就是Gradle。

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,而不是传统的XML。Gradle构建脚本是用Groovy编写的,也可以使用Kotlin编写,两者都是基于JVM的语言。

  • 老的Gradle项目可能会使用到Groovy编写,但目前spring官方比较推荐的Kotlin编写进行编写;
  • Gradle是JVM平台最受欢迎的构建系统,也是Android和Kotlin多平台项目的默认选择,它拥有丰富的社区插件生态系统。
  • Gradle可以使用其内置函数、第三方插件或自定义构建逻辑自动执行各种软件构建场景。
  • Gradle提供了一种高级、声明式和富有表现力的构建语言,使阅读和编写构建逻辑变得很轻松。

Gradle除了支持Java之外还支持Android、Kotlin Multiplatform、Groovy、Scala、Javascript和C/C++等热门语言的构建工作:

所有常见的IDE都支持Gradle,包括Android Studio、IntelliJ IDEA、Visual Studio Code、Eclipse和NetBeans。

二、安装Gradle

1、下载安装

在使用之前首先得先进行安装,安装可以直接通过官网:https://gradle.org/releases/进行安装,再安装的时候,我们需要查看自己的idea版本对应的Gradle版本,因为Gradle不同版本之间的差距会比较大

  • 通过到idea安装路径下的***\IntelliJ IDEA 2023.2.3\plugins\gradle\lib 查看

    我这里使用的是idea2023的版本,对应的是Gradle8.4的版本

通过官方网站点击binary-only进行下载

2、配置环境变量

2.1、mac

安装好后配置环境变量
  1. 使用文本编辑器(如vim、nano等)打开~/.bash_profile文件。可以使用以下命令:
    nano ~/.bash_profile

  2. 在打开的文件中,添加以下内容:

powershell 复制代码
# 请将/path/to/your/gradle替换为实际的Gradle安装路径。
export GRADLE_HOME=/path/to/your/gradle
export PATH=$GRADLE_HOME/bin:$PATH
  1. :wq 保存文件并关闭文本编辑器。

  2. source ~/.bash_profile 认环境变量生效

  3. gradle -v 执行查看是否有(如果可以看到版本下面的可以省略)

  4. 如果还是不行,可以配置~/.zshrc文件配置

    //路径需要改为自己的
    export PATH=$PATH:/path/to/your/gradle/bin

  5. 然后执行、在查看版本
    source ~/.zshrc

2.2、windows

  1. 首先负责解压后的安装目录

  2. 接着我们需要配置相应的环境变量才能使用,打开环境变量配置面板:

  3. 添加环境变量GRADLE_HOME(只能是这个),变量值为刚刚存放的Gradle文件夹位置。接着我们在Path环境变量中添加对应的bin目录:

  4. 添加完成后,我们打开一个新的命令窗口,输入gradle -v命令查看是否配置生效:

3、配置国内国内镜像源

需要修改一下全局的maven仓库镜像为国内的,要不然下载会非常慢。

到安装路径的**/gradle-8.4/init.d 路径下创建一个 init.gradle文件,把下面的复制过去。

kotlin 复制代码
allprojects {
    repositories {
        def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/repository/public'
        def ALIYUN_JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter'

        maven {
            url ALIYUN_REPOSITORY_URL
            name 'Aliyun Public Repository'
        }

        jcenter {
            url ALIYUN_JCENTER_URL
            name 'Aliyun JCenter'
        }
    }
}

4、初始化Gradle项目

完成安装之后,我们可以尝试创建一个gradle项目,主要分为几种方式、可以在spring官网创建;也可以通过命令行创建;但一般我们最常用的肯定是直接通过idea进行创建。

这里掩饰idea进行创建,其他的方式可以百度查看。

  1. 打开idea进入创建页面,直接创建spring项目,选择Type选择Kotiln,在一些老的教程可能会叫创建Groovy,但目前新的以及官方都是推荐Kotiln,然后选择对应的jdk

    注意: 不同版本的Gradle对我们使用的IDEA版本同样存在兼容性问题,这里推荐使用IntelliJ IDEA 2023.3或更高版本,旧版本的IDEA可能会不支持当前的Gradle 8.4版本。

  2. 添加依赖,这里就添加了两个依赖做测试

  3. 加载项目

    Gradle不好的一点是的跨版本兼容性很差,所以每次创建时会重新下载一次,因此它指定了当前项目中使用的Gradle版本,使得不同的开发人员或CI/CD系统都能使用相同的Gradle版本来构建项目,从而提高项目的一致性和可移植性。当然好处是,它可以自动下载和使用正确版本的Gradle,无需手动安装或配置Gradle,使得项目的维护和协作更加方便,后续别人拿到我们这个项目的时候,不需要自己在系统中部署Gradle环境。

这个过程中可能会很卡,因为服务器在国外(建议挂梯)直到出现BUILD SUCCESSFUL之后,表示初始化完成:

4.1、项目结构

内容作用:

  • .gradle:Gradle自动生成的项目缓存目录。
  • .idea:这个是IDEA的项目配置目录,跟Gradle生成的没关系,无视掉就行。
  • gradle:包含JAR文件和Gradle Wrapper的配置。
    • gradle-wrapper.properties:编写gradle配置的文件。默认有指定gradle版本等信息
  • src:存放整个项目的源代码、测试等,这里面就是我们写代码的地方了。
    • main:编写所有项目核心代码。
    • test:编写项目测试代码。
  • build.gradle.kts:项目的gradle构建脚本。
  • gradlew:适用于macOS和Linux的使用Gradle Wrapper执行构建的脚本(这里的版本就是GradleWrapper指定的版本)
  • gradlew.bat:适用于Windows的使用Gradle Wrapper执行构建的脚本。
  • settings.gradle.kts:定义子项目列表的项目配置文件,也是最关键的设置文件。

其他的没啥作用,不需要管。

4.2、Gradle常用命令

这里我们使用GradleWapper提供的gradlew进行操作,使用方式其实和gradle命令是一样的,只是这里用的是生成的(注意Windows平台下需要使用gradlew.bat来运行

  • ./gradlew.bat task :windows

  • ./gradlew task :查看一下所有Gradle支持的任务(mac/linux)

  • ./gradlew run:将当前项目以JVM应用程序的形式运行,这个命令会自动编译并运行我们的项目

  • ./gradlew clean:可以拆分执行,比如先执行清除命令,和maven一样的

  • ./gradlew classes:编译成class文件

  • ./gradlew classes -q : #安静模式,只执行,不打印日志

  • ./gradlew build:快速执行一个完整的编译+测试流程来构建整个项目,并得到打包好的jar等文件

  • ./gradlew build -x test:过滤执行测试

如果觉得敲命令太累了,idea已经自动帮我们集成Gradle插件了,外层的包是分类,内层的对应的每一个命令,也可以自定义插件命令

三、项目配置

项目构建流程

1、配置文件介绍

1.1、设置文件settings.gradle

设置文件settings.gradle是整个Gradle项目的入口点

对于多项目来说,也是主配置文件,因为Gradle支持单项目和多项目的构建:

  • 对于单个项目构建,设置文件是可选的。
  • 对于多项目构建,设置文件必须存在,并在其中定义所有子项目。

settings.gradle.ktsbuild.gradle.kts文件一样,也是也是使用Kotlin语言进行编写。如果Groovy生成的就会创建一个settings.gradle文件,就是使用Groovy语言编写

kotlin 复制代码
rootProject.name = "gradle-test"  //当前项目的名称

include("common") //子项目名称
include("order")
1.1.1、单体项目
1.1.2、父子项目

一个项目的settings.gradle.kts文件只能有一个,build.gradle.kts可以每个子项目都有一个

1.2、构建文件gradle.build

但我们是Kotlin语言构建的gradle.build.kts文件

生成的格式如下:

kotlin 复制代码
plugins {
    java
    id("org.springframework.boot") version "3.2.1"
    id("io.spring.dependency-management") version "1.1.4"
}

group = "org.example"
version = "0.0.1-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_17
}

configurations {
    compileOnly {
        extendsFrom(configurations.annotationProcessor.get())
    }
}

repositories {
//    mavenCentral()
    maven{
        setUrl("https://maven.aliyun.com/repository/public/")
    }
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    compileOnly("org.projectlombok:lombok")
    annotationProcessor("org.projectlombok:lombok")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

在这个配置文件中,基本上是采用lambda语句编写的,对比起maven看起来会更加的简洁美观。所以说虽然Gradle依赖于JVM平台,但是仅支持Kotlin和Groovy,它们相比Java在语法上存在更大的优势,更适合编写这种类似脚本一样的配置文件。

下面来拆分介绍每一块

  • plugins函数:用作指定使用哪些插件
kotlin 复制代码
plugins {
    java //一些内部的可以简写,表示使用java语言,相当于:id("java")
    id("org.springframework.boot") version "3.2.1" //springboot,version函数用作指定的插件版本
    id("io.spring.dependency-management") version "1.1.4" //用作指定spring所管理的依赖的版本,spring有的依赖,就不需要自己去指定版本了,通过该插件统一配置
}

这里的group和version分别设置了当前项目所属的组名称和版本:

kotlin 复制代码
group = "org.example"
version = "0.0.1-SNAPSHOT"

表示指定的jdk版本

kotlin 复制代码
java {
    sourceCompatibility = JavaVersion.VERSION_17
}
  • configurations用作定义项目中使用的不同配置
kotlin 复制代码
configurations {
    compileOnly {   //注解处理相关配置,用于Lombok
        extendsFrom(configurations.annotationProcessor.get())
    }
}
  • repositories用于指定仓库,
kotlin 复制代码
repositories {
//    mavenCentral() //指定maven官方仓库
    maven{
        setUrl("https://maven.aliyun.com/repository/public/") //指定阿里镜像仓库
    }
}
  • 引入依赖
    • 同时引入两个相同的依赖时,默认引入最新版本的
kotlin 复制代码
dependencies{
    implementation("org.springframework.boot:spring-boot-starter-actuator") //引用依赖
		implementation(files("C:\\pangea\\messageClient\\1.3.5\\messageClient-1.3.5.jar")) //引入本地指定路径的依赖
		implementation(filesTree("pangea"))  //引入项目跟路径下的pangea包下的全部jar包依赖
		implementation("io.springfox:springfox-swagger-ui:2.9.2"){
			exclude("org.springframework") //排除指定依赖
		}
		implementation("org.springframework:spring-aop:6.1.1!!")   //添加双感叹号,表示多个版本时,使用该版本
		testImplementation("org.springframework.boot:spring-boot-starter-test") //仅在测试时导入

}

DependencyHandlerScope使用方法,也就是dependencies,因为dependencies内部引用的是使用的Kotlin语言编写的。

  • implementation: 用于添加项目的依赖项,这是最常用的方法。
  • api: 与 implementation 类似,但它会暴露依赖项给项目的所有模块(多项目配置中讲解)
  • compileOnly: 用于指定编译时依赖,但不会在运行时包含在最终构建结果中。
  • testImplementation: 用于添加测试时需要的依赖项。
  • androidTestImplementation: 用于添加Android测试时需要的依赖项。
  • kapt: 用于添加 Kotlin 注解处理器依赖项。
  • annotationProcessor: 用于添加 Java 注解处理器依赖项。
  • runtimeOnly:仅在运行时使用,不用于编译

1.3、自定义任务

java 复制代码
tasks.register("myTask"){ //第一个参数为任务名称,第二个参数使用Lambda编写任务具体操作
	doFirst{ //使用doFirst向任务队列首部插入新的Action,也就是要执行的内容
		println("自定义任务----插入都任务首位")
		println("addd")
	}


	doLast{ //向队列尾部插入Action
		println("插入到任务尾部")
	}
}

添加后,点击刷新后就会出现对应的任务名称,点击可以执行

  • 通过命令行执行:输入对应的任务名称即可

1.4、生命周期钩子

有些时候我们希望在Gradle的整个生命周期中的不同时段执行一些操作,我们可以使用官方提供的生命周期钩子函数。

  1. 构建初始阶段

    • gradle.settingsEvaluated() 完成项目的配置阶段之后调用(只能定义在 setting.gradle 或 init.gradle 脚本中)
    • gradle.projectsLoaded() 所有项目加载之后调用(只能定义在 setting.gradle 或 init.gradle 脚本中)
  2. 配置阶段

    • gradle.beforeProject() 每个项目完成配置之前调用(只能定义在 setting.gradle 或 init.gradle 脚本中)
    • gradle.afterProject() 每个项目完成配置之后调用
    • gradle.projectEvaluated() 所有项目全部完成配置之后调用
    • gradle.afterEvaluate() 整个配置阶段完成后调用
    • gradle.taskGraph.whenReady 全部任务图已经构建完成可以就绪后调用
  3. 执行阶段

    • gradle.taskGraph.beforeTask 执行每一个任务之前调用
    • gradle.taskGraph.afterTask 每一个任务执行完成之后调用
    • gradle.buildFinished 整个构建全部结束后调用

这里我们可以尝试编写一个钩子函数试试看:

kotlin 复制代码
var time: Long = 0
gradle.settingsEvaluated { //开始任务
	println("开始构建")
	time = System.currentTimeMillis()
}

gradle.taskGraph.afterTask {//结束任务
	val takeTime = System.currentTimeMillis() - time
	println("任务: $name 执行耗时: ${takeTime}ms")
	println("构建结束")
}

1.5、JVM语言混合编程

如果需要多种语言混合编程

kotlin 复制代码
plugins {
	java
	kotlin("jvm") version "1.8.22" //Kotlin/JVM插件
	id("application") //打包为可执行的应用,也可以直接使用application插件

}
  1. 先创建一个存放kotlin可执行文件的目录,和java同层

  2. 然后再编写kotlin可执行文件Student.kt,以kt结尾

  3. 编写kolin代码,创建一个实体,比Java要简单

kotlin 复制代码
package com.test

data class Student(val name: String, val age: Int)
  1. 再通过测试类去调用
java 复制代码
@SpringBootTest
class GradleSpringTestApplicationTests {

	@Test
	void contextLoads() {

		Student student = new Student("小明", 19);
		System.out.println(student);
	}

}

输出

1.6、依赖的传递

我们在使用多模块时可能会遇到这样的一个问题,现在有三个模块,并且具有以下依赖关联:

service-a

service-b implementation(service-a)

service-c implementation(service-b)

此时,从链式的依赖关系上来看,它们长这样:service-a -> service-b -> service-c

按照正常的传递关系来说,在B中应该是可以直接使用A中定义的内容的,因为依赖了A模块,同时,由于C依赖了B模块,那么理所应当,C也应该可以直接使用A中定义的内容,我们来看看是否真的如此:

java 复制代码
//A模块中定义
public class Test {
    public static void test() {
        System.out.println("Hello World!");
    }
}
java 复制代码
//B模块中定义
public class Main {
    public static void main(String[] args) {
        Test.test();
    }
}
java 复制代码
//C模块中定义
public class Main {
    public static void main(String[] args) {
        Test.test();   //找不到类Test,编译失败
    }
}

这就很奇怪了,在Maven中是完全可以实现传递依赖的,为什么到Gradle就不行了呢?这是因为implementation不支持依赖传递,因此,即使我们改变了B模块的依赖,此时C也无法通过传递的形式得到B包含的依赖,由于不需要处理传递依赖,在编译时只需要处理一层,因此速度会非常快,大部分情况下非常推荐使用implementation来进行依赖导入。

如果各位小伙伴需要实现传递依赖的效果,我们需要使用另一个插件提供的方法来导入依赖:

java 复制代码
plugins {
    `java-library`   //java-library提供了传递依赖api函数
}

dependencies {
    api(project(":common"))   //与implementation效果一样,但是支持传递依赖
    testImplementation(platform("org.junit:junit-bom:5.9.1"))
    testImplementation("org.junit.jupiter:junit-jupiter")
}

此时,模块B的依赖由于使用了api进行导入,我们在模块C中无论是使用api导入还是implementation导入B,都可以使用B中api函数导入的依赖了。

相关推荐
959y2 小时前
[Go 微服务] Kratos 使用的简单总结
开发语言·golang·kratos
虫小宝3 小时前
如何在Java中实现批量数据处理
java·开发语言
PeterClerk3 小时前
基于Pygame的贪吃蛇小游戏实现
开发语言·python·pygame
king888866663 小时前
Java中的AQS
java
冰暮流星3 小时前
软设之类的继承与泛化,多重继承
java·开发语言
虫小宝3 小时前
Java中的多线程与并发编程详解
java·开发语言
oNuoyi3 小时前
定位线上同步锁仍然重复扣费的Bug定位及Redis分布式锁解决方案
java·spring boot·redis·分布式
Easonmax3 小时前
【C++】 解决 C++ 语言报错:Undefined Reference
java·开发语言·c++
Lightning-py3 小时前
Python使用(...)连接字符串
开发语言·python
计算机平台作业答案讲解3 小时前
QT实现GIF动图显示(小白版,可直接copy使用)
服务器·开发语言·数据结构·数据库·c++·qt·动态规划