• Java Gradle


    目录

    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


    1. Gradle简介

    1.1 什么是Gradle

    今天来学一学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都是小语言,用来专门解决某一类任务。

    1.2 Gradle优点

    1.2.1 自动化构建

    就是许多操作自动化嘛,Maven也行,是一项老技术了。就像写 Java 的时候,如果没有构建工具,我们需要在控制台,通过javac先将 Java 文件编译为 class 文件,然后再用jar命令将 class 文件打包为 jar 包。有了自动化构建工具只需要一个命令或是点一个按钮就可以打出 jar包。

    1.2.2 Gradle相当于构建工具的进化版

    • Apache Ant:最初是用来构建Tomcat的,发布于2000,用Java编写,构建脚本是xml。早期用Eclipse开发时,就用Ant。有比较多的缺点:无法实时获取运行信息,对xml没有规定约束,项目比较大时,xml难维护。
    • Maven:2004年推出Maven,解决上述问题。构建工具也是xml,相比Ant提供了高级项目管理工具。缺点也有:xml长,不好维护;灵活性不好;连接仓库不方便。
    • Gradle:采用Groovy或Kotlin编写,汲取Ant与Maven优点。最初用于Android,现在在Java开发中也广泛应用。

    1.2.3 对于Gradle优点,官网是这么说的

    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 通过重新使用以前执行的输出,仅处理已更改的输入以及并行执行任务来快速完成任务。通俗点就是说,第二次构建,只构建我们修改代码相关的类,不会耗费时间来构建整个项目;
    • 强大 : Gradle 是 Android 的官方构建工具,并支持许多流行的语言和技术。

     

    1.3 Grade 的版本说明

    • V2.2.1 - 4.10.1 : 基本已经很少使用了;
    • V4.10.1: AndroidStudio 3.3.0 支持的最低 Gradle 版本;
    • V5.0 : Gradle 的一个比较里程碑的版本,这个版本支持了 Kotlin DSL;
    • V6.0.1: 目前使用较多的版本;
    • V6.1.1: 目前最新的版本,2020 年 1 月 15 日发布的。主要是改进了依赖关系管理中的功能集。

    2. Groovy语言基础

    Gradle 是一个构建工具,它的构建脚本是基于 Groovy 或是 Kotlin 语言编写的。

    Groovy 结合了 Java、Python、Ruby 等当下几大流行语言的优点。它可以说是从 Java 中衍生出来的,为什么这么说呢?因为它的语法和 Java 非常的相似,它的文件也是可以编译为 .class 文件,而且可以使用 Java 的类库。

    2.1 基础语法

    变量: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一样

    关键字:

    大差不差

    asassertbreakcaseenumextends
    catchclassconstcontinuefalseFinally
    defdefaultdoelseforgoto
    importininstanceofinterfaceifimplements
    newpullpackagereturnthrowstrait
    superswitchthisthrowtruetry
    while

    2.2 String 与 GString

    2.2.1 String

    在 Java 中我们用单引号(’’)来表示 char,用双引号("")表示字符串。但是在 Groovy 中字符串不仅可以用双引号 (""),而且单引号 (’’),三引号 ("’’")也可以。 

    1. class Example {
    2. static void main(String[] args) {
    3. String a = '单引号';
    4. String b = "双引号";
    5. String c = '''这是三引号
    6. Gradle专题
    7. Groovy语言基础''';
    8. println(a);
    9. println(b);
    10. println(c);
    11. }
    12. }

    输出结果 

    单引号
    双引号
    这是三引号 
        Gradle专题
        Groovy语言基础
     

    我们发现三引号(’’’ ‘’’)其实还可以换行,多行字符串也可以用三引号(’’’ ‘’’)来引用。不像 Java 一样我们如果字符串换行还需要用“ + 和 \n”连接起来。

    2.2.2 插值字符串 GString

    所谓插值,就是用 ${变量名}读取该变量的值,而拼接起来的字符串。

    1. class Example {
    2. static void main(String[] args) {
    3. def a = 'Gradle专题';
    4. def b = "${a} Groovy语言基础"; //插值字符串 GStringImpl
    5. println(a.class);
    6. println(b.class);
    7. println(b);
    8. }
    9. }

    class java.lang.String
    class org.codehaus.groovy.runtime.GStringImpl
    Gradle专题 Groovy语言基础 

     2.3 方法

    Groovy 的方法定义跟 Java 比较类似,它的返回类型可以用返回值的类型或是def定义,也可以使用 publicstatic,private等修饰。

    注意:方法不要定义在 main 方法里面。

    2.4 逻辑控制

    • 顺序执行: 就是按顺序一步步执行。
    • 条件判断: 这个就是我们 Java 中的if/elseswitch/case
    • 循环语句: 跟 Java 中一样还是whilefor.

    Tips: 虽然 Groovy 的逻辑控制和 Java 中是一样的,但是 Groovy 又扩展了一些新功能。其中条件语句的if/else和循环语句的while与 Java 中是一样的,但是条件语句的switch/case和循环语句中的for, Groovy 在 Java 的基础上做了扩展。

    2.4.1 switch/case 语句

    1. class Example {
    2. static void main(String[] args) {
    3. def x = 0.98
    4. //def x = 3
    5. def result
    6. switch (x){
    7. case [4,5,6,'Gradle']: //列表
    8. result = 'list'
    9. break
    10. case 3..11:
    11. result = 'range' //范围
    12. break
    13. case Integer:
    14. result = 'Integer' //类型
    15. break
    16. case BigDecimal:
    17. result = 'BigDecimal'//类型
    18. break
    19. default:
    20. result = 'default'
    21. break
    22. }
    23. println(result)
    24. };
    25. }

    //x = 0.98时输出结果为
    BigDecimal
    //x = 3时输出结果为
    range 

     相较于 Java 的switch/case,Groovy 它的判断类型可以是任何类型。

    2.4.2 for循环

    Groovy 除了支持 Java 的for(int i = 0;i < length;i++)for(int i :array)形式的循环语句,还支持以下形式的循环语句:

    1. class Example {
    2. static void main(String[] args) {
    3. //1 对范围的for循环
    4. def sum = 0
    5. for (i in 0..100){
    6. sum += i
    7. }
    8. println("0到100的和为:"+sum)
    9. //2 对List的循环
    10. def sumList = 0;
    11. for (i in [1,2,3,4,5,6,7,8,9,10]){
    12. sumList += i
    13. }
    14. println("0到10的和为:"+sumList)
    15. //3 对Map的循环
    16. def sumMap = 0
    17. for (i in ['张三':21,'李四':25,'王五':36]){
    18. sumMap += i.value
    19. println i.key
    20. }
    21. println("他们的年龄和为:"+sumMap)
    22. };
    23. }

    0到100的和为:5050
    0到10的和为:55
    张三
    李四
    王五
    他们的年龄和为:82

    2.5 闭包

    闭包就是一段用 {} 包起来的代码块,使用方法和方法类型,可以命名,可以传参,可以被调用。

    1. class Example {
    2. static void main(String[] args) {
    3. //1 定义一个闭包
    4. def closer = {
    5. println "Gradle专题之Groovy语法"
    6. }
    7. //2 闭包的两种调用方式
    8. closer.call()
    9. closer()
    10. };
    11. }

     建议大家使用第一种方式去调用,以免和方法的调用混淆。

    上面定义的是无参的闭包,下面我们定义一个传参的闭包:

    1. class Example {
    2. static void main(String[] args) {
    3. //1 定义一个传参的闭包
    4. def closer = {
    5. String name -> println "${name}专题之Groovy语法"
    6. }
    7. closer.call('Gradle')
    8. };
    9. }

    2.6 IO操作

    2.6.1 文件读取

    1. class Example {
    2. static void main(String[] args) {
    3. def filePath = "D:/groovy.txt"
    4. def file = new File(filePath)
    5. file.eachLine {
    6. println it
    7. }
    8. };
    9. }
    10. ----------或是我们也可以像下面这么简洁---------
    11. class Example {
    12. static void main(String[] args) {
    13. def filePath = "D:/groovy.txt"
    14. def file = new File(filePath)
    15. println file.text
    16. };
    17. }

     2.6.2 文件写入

    1. class Example {
    2. static void main(String[] args) {
    3. def filePath = "D:/groovy.txt"
    4. def file = new File(filePath)
    5. file.withPrintWriter {
    6. it.println("Gradle专题")
    7. it.println("Groovy语言")
    8. it.println("文件写入")
    9. }
    10. };
    11. }

    2.7 数据结构

    常用的主要有:列表,范围,映射。跟 Java 的数据结构比较类似。

    2.7.1 列表

    1. class Example {
    2. static void main(String[] args) {
    3. // Java的定义方式
    4. def list = new ArrayList() //定义一个空的列表
    5. //groovy中定义
    6. def list2 = [] //定义一个空的列表
    7. def list3 = [1,2,3,4] //定义一个非空的列表
    8. println list2.class
    9. println list3.class
    10. };
    11. }
    12. --------------输出----------------
    13. class java.util.ArrayList
    14. class java.util.ArrayList
    15. ----------------------------------

    数组:

    1. //在groovy中使用as关键字定义数组
    2. def array = [1,2,3,4] as int[]
    3. //或者使用强类型的定义方式
    4. int[] array2 = [1,2,3]

     2.7.2 范围

    1. class Example {
    2. static void main(String[] args) {
    3. //范围的定义
    4. def range = 1..15
    5. //范围的使用
    6. //第一个元素的值
    7. println ("第一个元素的值:"+range[0])
    8. //是否包含8
    9. println ("是否包含8 "+range.contains(8))
    10. //范围的起始值
    11. println ("范围的起始值:"+range.from)
    12. //范围的结束值
    13. println ("范围的结束值:"+range.to )
    14. };
    15. }
    16. --------------输出----------------
    17. 第一个元素的值:1
    18. 是否包含8 true
    19. 范围的起始值:1
    20. 范围的结束值:15
    21. ----------------------------------

     2.7.3 映射

    在 Groovy 中定义映射 (MAP) 和 List 类似使用[]并且要指明它的键 (key)和值 (value),默认的实现类为java.util.LinkedHashMap.

    1. class Example {
    2. static void main(String[] args) {
    3. //1 映射的定义
    4. def swordsman = [one:'张三丰',two:'金毛狮王谢逊',three:'张无忌']
    5. //2 映射的使用
    6. println swordsman['one']
    7. println swordsman.get('two')
    8. println swordsman.three
    9. //3 添加元素
    10. swordsman.four = '成坤'
    11. println swordsman
    12. //4 groovy中,可以添加一个复杂的元素,比如添加一个map
    13. swordsman.five = [a:1,b:2]
    14. println swordsman
    15. };
    16. }
    17. ------------------输出----------------------
    18. 张三丰
    19. 金毛狮王谢逊
    20. 张无忌
    21. [one:张三丰, two:金毛狮王谢逊, three:张无忌, four:成坤]
    22. [one:张三丰, two:金毛狮王谢逊, three:张无忌, four:成坤, five:[a:1, b:2]]
    23. --------------------------------------------

    2.8 小结

    • Groovy 的语法和 Java 非常相似;
    • Groovy 中定义变量可以使用def系统会自动帮我们转换为具体类型;
    • 定义基本数据类型时不需要导包,Groovy 系统包含那些包;
    • Groovy 的字符串可以用,单引号,双引号,三引号。换可以支持字符串的插值;
    • Groovy 的方法跟 Java 一样不能定义在方法内部;
    • Groovy 的switch/case支持任意类型的判断;
    • Groovy 的for支持列表,范围和映射的遍历;
    • Groovy 的闭包灵活且强大建议使用第一种方式调用;
    • Groovy 的数组使用as关键字定义;
    • Groovy 的映射必须指明键和值。

    3. Gradle配置详解

    3.1 SpringBoot项目结构

     

    1. 根目录下的 build.gradle: 顶级构建文件,配置 Gradle 版本和 Maven 依赖;
    2. 各个模块下的 build.gralde: 该模块打包和签名配置,及模块的依赖;
    3. gradle 文件夹: 配置 gradel-wrapper;
    4. setting.gradle 文件: 添加编译的所有模块;
    5. gradle.properties 文件: 项目范围的梯度设置,编译内存,Gradle 并发性等设置。;
    6. gradlew 和 gradlew.bat 文件: Gradle 启动脚本文件;
    7. .gradle 文件夹: 编译时的缓存文件夹。

    重点学习下build.gradlesetting.gradle

    3.2 build.gradle

    需要注意的是,脚本内容的执行是有先后顺序的,一般来说按buildscript->plugins->repositories->dependencies->dependencyManagement。

    1. buildscript {
    2. repositories {
    3. maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
    4. }
    5. dependencies {
    6. classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.4.5'
    7. }
    8. }
    9. plugins {
    10. id 'org.springframework.boot' version '2.4.5'
    11. id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    12. id 'java'
    13. }
    14. group = 'com.zkcloud'
    15. version = '1.0.0'
    16. repositories {
    17. maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
    18. }
    19. ext {
    20. set('springCloudVersion', "2020.0.2")
    21. }
    22. dependencies {
    23. implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    24. implementation 'org.springframework.boot:spring-boot-starter-actuator'
    25. implementation 'com.github.ben-manes.caffeine:caffeine:2.8.8'
    26. }
    27. dependencyManagement {
    28. imports {
    29. mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    30. }
    31. }

    3.2.1 构建脚本-buildscript

    1. buildscript {
    2. repositories {
    3. /*从哪儿下构建插件*/
    4. maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
    5. }
    6. dependencies {
    7. /*下什么构建插件*/
    8. classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.4.5'
    9. }
    10. }

     其中:repositories指定仓库的位置,dependencies指定了插件类型和版本

    3.2.2 插件-plugins

    1. plugins {
    2. id 'org.springframework.boot' version '2.4.5'
    3. id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    4. id 'java'
    5. }

    id 'org.springframework.boot' 引入了springboot插件,可执行springboot项目相关的task指令

    id 'io.spring.dependency-management' 引入了依赖管理相关的插件,可执行依赖相关的指令

    id 'java' 引入了Java插件,就可以支持java编译、运行、打包等task指令

    3.2.3 仓库-repositories

    1. repositories {
    2. maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
    3. }

    用于指定项目中的Jar包依赖,需要从哪里下载,由于各种各样的原因,我们需要改成国内的镜像

    比如,阿里的镜像 :maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }

    3.2.4 依赖-dependencies

    1. dependencies {
    2. implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    3. implementation 'org.springframework.cloud:spring-cloud-starter-config'
    4. implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
    5. implementation 'org.springframework.boot:spring-boot-starter-web'
    6. implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    7. implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    8. implementation 'com.baomidou:mybatis-plus-boot-starter:3.1.0'
    9. implementation 'com.alibaba:druid-spring-boot-starter:1.1.9'
    10. implementation 'org.apache.commons:commons-pool2'
    11. implementation 'mysql:mysql-connector-java'
    12. }

    显然,是项目中引入外部依赖的关键,类比于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' 

    3.2.5 依赖管理-dependencyManagement

    1. dependencyManagement {
    2. imports {
    3. mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    4. }
    5. }

    这一块主要是依赖管理相关,如果这涉及到,多模块、父子模块,那么在这里,可以界定,全局的依赖版本,记住一点的是,这个地方并不会引入依赖,指定提前界定好,那么在各模块中就不用写版本号了,比如前面说的dependencies里面的依赖,和springboot“同宗同族”的,基本上都没有指定版本,就是因为这里已经指定了springboot的版本,方便依赖的版本管理。

    3.3 settings.gradle

    settings.gradle是模块Module配置文件,主要是用于配置子模块,根目录下的setting.gradle脚本文件是针对module的全局配置

    1. // 为指定父模块的名称 平台根
    2. rootProject.name = 'project-root'
    3. //包含子系统以及模块
    4. include ':project-core'
    5. //Hello系统模块的加载
    6. include ':project-hello'
    7. //World系统模块的加载
    8. include ':project-world'

     3.4 gradle流程

    初始化阶段

    首先解析settings.gradle

    Configration阶段:

    解析每个Project中的build.gradle,解析过程中并不会执行各个build.gradle中的task

    经过Configration阶段,Project之间及内部Task之间的关系就确定了。一个 Project 包含很多 Task,每个 Task 之间有依赖关系。

    Configuration会建立一个有向图来描述 Task 之间的依赖关系,所有Project配置完成后,会有一个回调project.afterEvaluate,表示所有的模块都已经配置完了。

    4. Gradle Wrapper详解

    4.1 什么是Gradle Wrapper

    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也可以来构建项目。

    4.2 配置Gradle Wrapper

    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

    1. distributionBase: Gradle 解包后存储的父目录;
    2. distributionPath: distributionBase指定目录的子目录。distributionBase+distributionPath就是 Gradle 解包后的存放的具体目录;
    3. distributionUrl: Gradle 指定版本的压缩包下载地址;
    4. zipStoreBase: Gradle 压缩包下载后存储父目录;
    5. zipStorePath: zipStoreBase指定目录的子目录。zipStoreBase+zipStorePath就是 Gradle 压缩包的存放位置。

  • 相关阅读:
    PyTorch 深度学习之加载数据集Dataset and DataLoader(七)
    无人自动驾驶技术研发中具有重要性
    A-Level物理例题解析及练习Projectile Motion
    Java作业7-Java异常处理
    JVM_JVM启动参数及堆内存分布及GC触发条件
    《了解CV和RoboMaster视觉组》完结啦!
    [HDCTF 2023]YamiYami
    智慧水务:数字孪生污水处理厂,3D可视化一键管控
    ArcGIS绘制地球
    saltstack运维工具包salt-api代码记录
  • 原文地址:https://blog.csdn.net/weixin_45734473/article/details/133125895