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 的官方构建工具,并支持许多流行的语言和技术。

 Java Gradle_第1张图片

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一样

关键字:

大差不差

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

2.2 String 与 GString

2.2.1 String

在 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”连接起来。

2.2.2 插值字符串 GString

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

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语言基础 

 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 语句

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 它的判断类型可以是任何类型。

2.4.2 for循环

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

2.5 闭包

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

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')
   };
}

2.6 IO操作

2.6.1 文件读取

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
    };
}

 2.6.2 文件写入

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("文件写入")
        }
   };
}

2.7 数据结构

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

2.7.1 列表

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]

 2.7.2 范围

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

----------------------------------

 2.7.3 映射

在 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]]
--------------------------------------------

2.8 小结

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

3. Gradle配置详解

3.1 SpringBoot项目结构

 Java Gradle_第2张图片

  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。

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指定了插件类型和版本

3.2.2 插件-plugins

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指令

3.2.3 仓库-repositories

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

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

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

3.2.4 依赖-dependencies

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' 

3.2.5 依赖管理-dependencyManagement

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

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

3.3 settings.gradle

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

// 为指定父模块的名称 平台根
rootProject.name = 'project-root'
//包含子系统以及模块
include ':project-core'
//Hello系统模块的加载
include ':project-hello'
//World系统模块的加载
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 压缩包的存放位置。

你可能感兴趣的:(Java面试指南,java,spring,boot,Gradle)