目录
1. Gradle简介
1.1 什么是Gradle
1.2 Gradle优点
1.2.1 自动化构建
1.2.2 Gradle相当于构建工具的进化版
1.2.3 对于Gradle优点,官网是这么说的
1.3 Grade 的版本说明
2. Groovy语言基础
2.1 基础语法
2.2 String 与 GString
2.2.1 String
2.2.2 插值字符串 GString
2.3 方法
2.4 逻辑控制
2.4.1 switch/case 语句
2.4.2 for循环
2.5 闭包
2.6 IO操作
2.6.1 文件读取
2.6.2 文件写入
2.7 数据结构
2.7.1 列表
2.7.2 范围
2.7.3 映射
2.8 小结
3. Gradle配置详解
3.1 SpringBoot项目结构
3.2 build.gradle
3.2.2 插件-plugins
3.2.3 仓库-repositories
3.2.4 依赖-dependencies
3.2.5 依赖管理-dependencyManagement
3.3 settings.gradle
3.4 gradle流程
4. Gradle Wrapper详解
4.1 什么是Gradle Wrapper
4.2 配置Gradle Wrapper
今天来学一学Gradle,相比于之前的Maven,现在Gradle可是大名鼎鼎。同样都是项目构建工具,Gradle有什么独特之处?Gradle官网中是这样介绍的
Gradle is an open-source build automation tool focused on flexibility and performance. Gradle build scripts are written using a Groovy or Kotlin DSL. —官网
翻译成中文就是,Gradle 是专注于灵活性和性能的开源构建自动化工具。Gradle 构建脚本是使用 Groovy 或 Kotlin DSL 编写的。
Groovy和DSL都是小语言,用来专门解决某一类任务。
就是许多操作自动化嘛,Maven也行,是一项老技术了。就像写 Java 的时候,如果没有构建工具,我们需要在控制台,通过javac
先将 Java 文件编译为 class 文件,然后再用jar
命令将 class 文件打包为 jar 包。有了自动化构建工具只需要一个命令或是点一个按钮就可以打出 jar包。
Accelerate developer productivity
翻译过来就是:加快开发人员生产力
From mobile apps to microservices, from small startups to big enterprises, Gradle helps teams build, automate and deliver better software, faster.
翻译过来就是:从移动应用程序到微服务,从小型初创公司到大型企业,Gradle 可以帮助团队更快地构建,自动化和交付更好的软件。
Gradle 它汲取了 Ant 和 Maven 的优点,吸收了 Ant 的 task 思想,和 Maven 的规范化和仓库概念。采用 Groovy 或是 Kotlin 语言编写,但是它的代码量更少,可读性更强。
Gradle 具有以下 3 大特性:
Gradle 是一个构建工具,它的构建脚本是基于 Groovy 或是 Kotlin 语言编写的。
Groovy 结合了 Java、Python、Ruby 等当下几大流行语言的优点。它可以说是从 Java 中衍生出来的,为什么这么说呢?因为它的语法和 Java 非常的相似,它的文件也是可以编译为 .class 文件,而且可以使用 Java 的类库。
变量:def
引入包:和Java一样
Tips:在开发 Groovy 时,以下一些库,我们不需要显式的去引入它们,系统已经包含了这些库。
import java.lang.*
import java.util.*
import java.io.*
import java.net.*import groovy.lang.*
import groovy.util.*import java.math.BigInteger
import java.math.BigDecimal
注释和分号:和Java一样
关键字:
大差不差
as | assert | break | case | enum | extends |
---|---|---|---|---|---|
catch | class | const | continue | false | Finally |
def | default | do | else | for | goto |
import | in | instanceof | interface | if | implements |
new | pull | package | return | throws | trait |
super | switch | this | throw | true | try |
while |
在 Java 中我们用单引号(’’)来表示 char,用双引号("")表示字符串。但是在 Groovy 中字符串不仅可以用双引号 (""),而且单引号 (’’),三引号 ("’’")也可以。
class Example {
static void main(String[] args) {
String a = '单引号';
String b = "双引号";
String c = '''这是三引号
Gradle专题
Groovy语言基础''';
println(a);
println(b);
println(c);
}
}
输出结果
单引号
双引号
这是三引号
Gradle专题
Groovy语言基础
我们发现三引号(’’’ ‘’’)其实还可以换行,多行字符串也可以用三引号(’’’ ‘’’)来引用。不像 Java 一样我们如果字符串换行还需要用“ + 和 \n”
连接起来。
所谓插值,就是用 ${变量名}
读取该变量的值,而拼接起来的字符串。
class Example {
static void main(String[] args) {
def a = 'Gradle专题';
def b = "${a} Groovy语言基础"; //插值字符串 GStringImpl
println(a.class);
println(b.class);
println(b);
}
}
class java.lang.String
class org.codehaus.groovy.runtime.GStringImpl
Gradle专题 Groovy语言基础
Groovy 的方法定义跟 Java 比较类似,它的返回类型可以用返回值的类型或是def
定义,也可以使用 public
,static
,private
等修饰。
注意:方法不要定义在 main 方法里面。
if/else
和switch/case
。while
和for
.Tips: 虽然 Groovy 的逻辑控制和 Java 中是一样的,但是 Groovy 又扩展了一些新功能。其中条件语句的
if/else
和循环语句的while
与 Java 中是一样的,但是条件语句的switch/case
和循环语句中的for
, Groovy 在 Java 的基础上做了扩展。
class Example {
static void main(String[] args) {
def x = 0.98
//def x = 3
def result
switch (x){
case [4,5,6,'Gradle']: //列表
result = 'list'
break
case 3..11:
result = 'range' //范围
break
case Integer:
result = 'Integer' //类型
break
case BigDecimal:
result = 'BigDecimal'//类型
break
default:
result = 'default'
break
}
println(result)
};
}
//x = 0.98时输出结果为
BigDecimal
//x = 3时输出结果为
range
相较于 Java 的switch/case
,Groovy 它的判断类型可以是任何类型。
Groovy 除了支持 Java 的for(int i = 0;i < length;i++)
和for(int i :array)
形式的循环语句,还支持以下形式的循环语句:
class Example {
static void main(String[] args) {
//1 对范围的for循环
def sum = 0
for (i in 0..100){
sum += i
}
println("0到100的和为:"+sum)
//2 对List的循环
def sumList = 0;
for (i in [1,2,3,4,5,6,7,8,9,10]){
sumList += i
}
println("0到10的和为:"+sumList)
//3 对Map的循环
def sumMap = 0
for (i in ['张三':21,'李四':25,'王五':36]){
sumMap += i.value
println i.key
}
println("他们的年龄和为:"+sumMap)
};
}
0到100的和为:5050
0到10的和为:55
张三
李四
王五
他们的年龄和为:82
闭包就是一段用 {} 包起来的代码块,使用方法和方法类型,可以命名,可以传参,可以被调用。
class Example {
static void main(String[] args) {
//1 定义一个闭包
def closer = {
println "Gradle专题之Groovy语法"
}
//2 闭包的两种调用方式
closer.call()
closer()
};
}
建议大家使用第一种方式去调用,以免和方法的调用混淆。
上面定义的是无参的闭包,下面我们定义一个传参的闭包:
class Example {
static void main(String[] args) {
//1 定义一个传参的闭包
def closer = {
String name -> println "${name}专题之Groovy语法"
}
closer.call('Gradle')
};
}
class Example {
static void main(String[] args) {
def filePath = "D:/groovy.txt"
def file = new File(filePath)
file.eachLine {
println it
}
};
}
----------或是我们也可以像下面这么简洁---------
class Example {
static void main(String[] args) {
def filePath = "D:/groovy.txt"
def file = new File(filePath)
println file.text
};
}
class Example {
static void main(String[] args) {
def filePath = "D:/groovy.txt"
def file = new File(filePath)
file.withPrintWriter {
it.println("Gradle专题")
it.println("Groovy语言")
it.println("文件写入")
}
};
}
常用的主要有:列表,范围,映射。跟 Java 的数据结构比较类似。
class Example {
static void main(String[] args) {
// Java的定义方式
def list = new ArrayList() //定义一个空的列表
//groovy中定义
def list2 = [] //定义一个空的列表
def list3 = [1,2,3,4] //定义一个非空的列表
println list2.class
println list3.class
};
}
--------------输出----------------
class java.util.ArrayList
class java.util.ArrayList
----------------------------------
数组:
//在groovy中使用as关键字定义数组
def array = [1,2,3,4] as int[]
//或者使用强类型的定义方式
int[] array2 = [1,2,3]
class Example {
static void main(String[] args) {
//范围的定义
def range = 1..15
//范围的使用
//第一个元素的值
println ("第一个元素的值:"+range[0])
//是否包含8
println ("是否包含8 "+range.contains(8))
//范围的起始值
println ("范围的起始值:"+range.from)
//范围的结束值
println ("范围的结束值:"+range.to )
};
}
--------------输出----------------
第一个元素的值:1
是否包含8 true
范围的起始值:1
范围的结束值:15
----------------------------------
在 Groovy 中定义映射 (MAP) 和 List 类似使用[]
并且要指明它的键 (key)和值 (value),默认的实现类为java.util.LinkedHashMap
.
class Example {
static void main(String[] args) {
//1 映射的定义
def swordsman = [one:'张三丰',two:'金毛狮王谢逊',three:'张无忌']
//2 映射的使用
println swordsman['one']
println swordsman.get('two')
println swordsman.three
//3 添加元素
swordsman.four = '成坤'
println swordsman
//4 groovy中,可以添加一个复杂的元素,比如添加一个map
swordsman.five = [a:1,b:2]
println swordsman
};
}
------------------输出----------------------
张三丰
金毛狮王谢逊
张无忌
[one:张三丰, two:金毛狮王谢逊, three:张无忌, four:成坤]
[one:张三丰, two:金毛狮王谢逊, three:张无忌, four:成坤, five:[a:1, b:2]]
--------------------------------------------
def
系统会自动帮我们转换为具体类型;switch/case
支持任意类型的判断;for
支持列表,范围和映射的遍历;as
关键字定义;重点学习下build.gradle和setting.gradle
需要注意的是,脚本内容的执行是有先后顺序的,一般来说按buildscript->plugins->repositories->dependencies->dependencyManagement。
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.4.5'
}
}
plugins {
id 'org.springframework.boot' version '2.4.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.zkcloud'
version = '1.0.0'
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
}
ext {
set('springCloudVersion', "2020.0.2")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'com.github.ben-manes.caffeine:caffeine:2.8.8'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
3.2.1 构建脚本-buildscript
buildscript {
repositories {
/*从哪儿下构建插件*/
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
/*下什么构建插件*/
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.4.5'
}
}
其中:repositories
指定仓库的位置,dependencies
指定了插件类型和版本
plugins {
id 'org.springframework.boot' version '2.4.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
id 'org.springframework.boot' 引入了springboot插件,可执行springboot项目相关的task指令
id 'io.spring.dependency-management' 引入了依赖管理相关的插件,可执行依赖相关的指令
id 'java' 引入了Java插件,就可以支持java编译、运行、打包等task指令
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
}
用于指定项目中的Jar包依赖,需要从哪里下载,由于各种各样的原因,我们需要改成国内的镜像
比如,阿里的镜像 :maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'com.baomidou:mybatis-plus-boot-starter:3.1.0'
implementation 'com.alibaba:druid-spring-boot-starter:1.1.9'
implementation 'org.apache.commons:commons-pool2'
implementation 'mysql:mysql-connector-java'
}
显然,是项目中引入外部依赖的关键,类比于maven,可以发现是类似的
implementation 是springboot插件提供的task指令,指定作用域为:从编译、打包到运行的整个过程都有效,类似于maven的scope节点
可以用 groupId artifactId version 指定一个具体依赖
implementation groupId 'com.baomidou' artifactId 'mybatis-plus-boot-starter' version '3.1.0'
也可以用
implementation 'com.baomidou:mybatis-plus-boot-starter:3.1.0'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
这一块主要是依赖管理相关,如果这涉及到,多模块、父子模块,那么在这里,可以界定,全局的依赖版本,记住一点的是,这个地方并不会引入依赖,指定提前界定好,那么在各模块中就不用写版本号了,比如前面说的dependencies里面的依赖,和springboot“同宗同族”的,基本上都没有指定版本,就是因为这里已经指定了springboot的版本,方便依赖的版本管理。
settings.gradle是模块Module配置文件,主要是用于配置子模块,根目录下的setting.gradle脚本文件是针对module的全局配置
// 为指定父模块的名称 平台根
rootProject.name = 'project-root'
//包含子系统以及模块
include ':project-core'
//Hello系统模块的加载
include ':project-hello'
//World系统模块的加载
include ':project-world'
初始化阶段
首先解析settings.gradle
Configration阶段:
解析每个Project中的build.gradle,解析过程中并不会执行各个build.gradle中的task
经过Configration阶段,Project之间及内部Task之间的关系就确定了。一个 Project 包含很多 Task,每个 Task 之间有依赖关系。
Configuration会建立一个有向图来描述 Task 之间的依赖关系,所有Project配置完成后,会有一个回调project.afterEvaluate,表示所有的模块都已经配置完了。
The recommended way to execute any Gradle build is with the help of the Gradle Wrapper (in short just “Wrapper”). The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. As a result, developers can get up and running with a Gradle project quickly without having to follow manual installation processes saving your company time and money.—官方
我们翻译过来大致意思就是:官方建议任何 Gradle 构建方法在 Gradle Wrapper 帮助下运行。Gradle Wrapper 它是一个脚本,调用了已经声明的 Gradle 版本,并且我们编译时需要事先下载它。所以,开发者能够快速的启动并且运行 Gradle 项目,不用再手动安装,从而节省了时间成本。
我们可以称 Gradle Wrapper 为 Gradle 包装器,是将 Gradle 再次包装。让所有的 Gradle 构建方法在 Gradle 包装器的帮助下运行。
使用Gradle Wrapper的好处就是方便项目共同开发与管理,在Wrapper中定义好Gradle版本,这样本地没有Gradle也可以来构建项目。
gradle-wrapper.properties
文件指明了 Gradle 的版本号,和 Gradle 运行时的行为属性文件。下面我们具体看下这个文件的内容:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionBase
指定目录的子目录。distributionBase+distributionPath
就是 Gradle 解包后的存放的具体目录;zipStoreBase
指定目录的子目录。zipStoreBase+zipStorePath
就是 Gradle 压缩包的存放位置。