先问个问题:你们项目中常用的构建工具是什么?
我猜,大部分小伙伴应该都会不约而同的说:Maven。
说到 Maven ,相信大多数的 Java 开发者一定不会不陌生,当然,有实力的同学可以把精通打在公屏上(简历上)。
但咱们今天的主角并不是它,而是另外一个:Gradle
Gradle 也是一个自动化构建的开源工具,它的构建脚本是基于 Groovy 或者 Kotlin 的特定领域来实现的,而不是我们在 Maven 中使用的 XML。
这时肯定会有小伙伴会问,Maven 不是已经能够满足我们平时的项目构建功能需求了吗,为什么有整一个 Gradle 出来呢?
存在即合理。
我们来看一下 gradle 的几个优势:
-
简洁性
相信不少人都体验过,在一个比较大的项目中,其依赖可能有几十个,而维护的 XML 可能就有上百行,而且每添加一个依赖,至少都要添加三行。而使用 Gradle ,仅需要一行就能实现。依赖配置的大小是其三分之一,而且维护起来更加简洁方便。
-
灵活性
从这一点来看,gradle 的灵活性可谓是甩了 Maven 好几条街。
在 Maven 中如果你想对构建增加一些自定义的逻辑,大部分情况下需要引用外部的插件,非常麻烦。而对于 Gradle 来说,只需要编写简单的脚本即可使用。当然,前期还是需要一点脚本语言学习的成本,但是一旦你熟悉了,后面想对其任意扩展就轻而易举的事了。
-
速度快
Gradle 使用构建缓存、守护进程等方式提高编译速度。
Gradle 官网上提供了各场景的测试性能对比:
比如,将 Apache Commons Lang 3 项目从 Maven 迁移到了 Gradle,测试的结果是:Gradle在运行测试上快了1.7倍,而在开启cache的时候快了30倍!
又或者是,10个模块的多项目构建的常见任务的结果,类似于微服务的应用工程。每个子项目有50个源文件和50个测试源文件,测试的结果是:Gradle在纯净构建上快2-3倍,而在增量构建上快了7倍,在Gradle任务输出被缓存的情况下可以提升至14倍!
- 在所有场景下,Gradle 都至少比 Maven 快2倍
- 当增量构建时,Gradle 比 Maven 快7-85倍,子项目越多,Gradle 快的越多
- 当 Gradle 的构建缓存可以解析任务输出的时候,Gradle 比 Maven 快 3-30 倍
上述测试数据来自 Gradle 官方文档
这也是为什么 Spring Boot 2.3.0.M1 后选择从 Maven 迁移到 Gradle 的原因,因为它实在是太快了。
-
兼容性
支持 maven 和 ant 仓库、支持多个语言,比如 Java、Kotlin、Groovy 等。
Gradle 快速入门
创建一个 Gradle 的工程后,在工程结构上它与 Maven 工程不一样的,主要是在 Maven 配置是在 pom.xml
文件 ,而 Gradle 则是在 build.gradle
。
我们知道在 Maven 的 pom.xml
会定义一些依赖、仓库地址、版本信息等。而在 Gradle 的 build.gradle
其实也是大同小异,只不过是配置的写法会有些稍微不同,可以说是更加简单和简洁。
repositories
Gradle 支持 Maven 和 Ant 的仓库配置。下面贴上使用 Maven 仓库的配置方式,小伙伴们可以根据实际场景自行选择仓库镜像源。
repositories {
// 中央仓库
mavenCentral()
// 腾讯云镜像仓库
maven {
url "http://mirrors.cloud.tencent.com/nexus/repository/maven-public/"
}
// 私服配置
maven {
name "xxx"
url "http://nexus.xxx.com"
credentials {
username "admin"
password "admin"
}
}
}
dependencies
作为项目管理工具,依赖管理必然是核心模块之一。
ext {
springBootVersion = "2.3.8.RELEASE"
}
dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
}
dependencies {
}
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
我们知道在 Maven中 dependencies 依赖是有 scope 的维度区分:
- compile:默认的依赖范围,在所有的classpath 中可用,同时它们也会被打包。
- provided:在编译和测试时有效,运行时不会引入。简单说就是非传递依赖。
- runtime:运行范围,运行和测试环境使用,编译时不用加入classpath,打包时候会加入。
- test:只有在测试编译和测试运行阶段可用
- systemt:与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。
当然,Gradle 也提供相对应 scope 的实现,只不过方式有些稍微的区别,我们看一下比较常见的定义:
// 类比 maven 中的 compile,依赖传递
api("org.springframework.boot:spring-boot-starter-web")
// 类比 maven 中的 provided,非依赖传递
implementation("org.springframework.boot:spring-boot-starter-web")
// 在编译时需要,但在运行时不需要的依赖项。
compileOnly ("org.projectlombok:lombok:1.18.18")
// 声明的依赖关系只在运行时需要,而不是在编译时
runtimeOnly
// 注释编译期间使用的处理器。
annotationProcessor "org.projectlombok:lombok:1.18.18"
// 只在测试时依赖,当然还有 testCompileOnly、testRuntimeOnly等等
testImplementation("org.springframework.boot:spring-boot-starter-test")
plugins
没错,这里的 plugins 对应的就是 maven 中的 plugins,不过 gradle 中的 plugins 更加的灵活、便捷。
我们可以直接使用 Gradle插件中心 公共插件,当然也可以通过编写 groovy 自定义插件。
可能有些同学会看到还有通过 apply
的方式,这种是老版本 2.1 之前的用法了。
plugins{
id 'java'
id 'org.springframework.boot' version '2.3.8.RELEASE'
}
上面可以看到 java
也是以插件的形式引入的,为什么 maven 中就不用了呢?
这里就需要简单讲一下 Gradle 的一些比较基础的概念。
Task(任务)是 Gradle 其中一个比较核心的概念,每个项目都是由多个 task 组成。比如说一个对于 Java 项目来说,一个项目的整个构建生命周期是包括:编译、打包、发布这几个操作,而每个操作可以理解为代表一个 task。
Gradle 的项目构建生命周期并不是 Gradle 的内建机制,而是由 Plugin 引入的。
在引入 java
插件后,同时也会引入如下的 task
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build
这里的 task 是不是跟 maven 中构建项目的操作很相似呢~
构建上传&发布
对于要把 jar 包发布到私服仓库的需求,我们可以借助 maven-publish
插件轻松实现。
plugins{
id 'java'
id 'maven-publish'
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
// 设置仓库地址
repositories {
maven {
name "maven-release"
url ""
credentials {
username "admin"
password "admin"
}
}
maven {
name "maven-snapshot"
url ""
credentials {
username "admin"
password "admin"
}
}
}
}
依赖检查
我们有时可能需要查看项目的引用依赖或者依赖传递信息,通过 gradle dependencies
查看依赖树。
如果是 maven 我们借助 idea 上的 maven-helper
的来取排查,这样子会更方便一点。
.....
总的来说,Gradle 整体比 Maven 更加灵活和高效,但是学习的成本和操作也会更加高一丢丢。
它更常用在 Android、Kotlin、Groovy 等语言开发的项目中,但是现在像 Spring、Hibernate 等这些开源项目也选择 Gradle 做为项目管理构件工具,足以说明它的一个未来发展趋势。所以说,尽管你可能现在用不上,但是技多不压身嘛。
以上是小年 Gradle 入门学习的一些总结,当然还有更多的学习技巧,后续会陆续分享。
普通的改变,将改变普通
我是宅小年,一个在互联网低调前行的小青年
关注公众号「宅小年」,个人博客 📖 edisonz.cn,阅读更多分享文章