百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Gradle 简易入门教程

toyiye 2024-06-21 12:18 6 浏览 0 评论

Gradle 是一种构建工具,它抛弃了基于XML的构建脚本,取而代之的是采用一种基于 Groovy(现在也支持 Kotlin)的内部领域特定语言。

Gradle特点

  1. Gradle是很成熟的技术,可以处理大规模构建
  2. Gradle对多语言、多平台支持性更好
  3. Gradle关注在构建效率上
  4. Gradle发布很频繁,重要feature开发计划透明化
  5. Gradle社区很活跃,并且增加迅速

安装Gradle

  • 从 官网 (https://gradle.org/install/)下载二进制文件。
  • 解压Zip文件,加入环境变量(在PATH中加入GRADLE_HOME/bin目录)

如果在安装过程中遇到问题,可以进一步查看官方的安装指南(https://gradle.org/install/)。最后验证一下 Gradle 是否工作正常

 gradle -v
 ------------------------------------------------------------
 Gradle 4.2.1
 ------------------------------------------------------------
 Build time: 2017-10-02 15:36:21 UTC
 Revision: a88ebd6be7840c2e59ae4782eb0f27fbe3405ddf
 Groovy: 2.4.12
 Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
 JVM: 1.8.0_162-ea (Oracle Corporation 25.162-b01)
 OS: Mac OS X 10.13.5 x86_64

Gradle快速体验

初始化一个项目

  • 创建一个 demo 目录
? mkdir gradle-demo
  • 初始化 Gradle 项目
? gradle init 
Starting a Gradle Daemon (subsequent builds will be faster)
BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

Gradle目录结构

我们看看上一步我们生成了什么文件

├── build.gradle ?
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar ?
│ └── gradle-wrapper.properties ?
├── gradlew ?
├── gradlew.bat ?
└── settings.gradle ?

? 当前项目的配置脚本

? Gradle Wrapper 的执行jar包(后续介绍)

? Gradle Wrapper 的配置文件

? Gradle Wrapper Unix 系执行脚本

? Gradle Wrapper Windows 系执行脚本

? 项目脚本设置

创建一个Task

Gradle提供了用于通过基于Groovy或Kotlin的DSL创建和配置。项目包括一组Task,每个Task执行一些基本操作。

  • 创建一个目录叫 src
  • 在src目录创建一个 myfile.txt
  • 在构建文件中定义一个名为Copy的类型 Task ,该任务将src目录复制到名为dest的新目录

groovy代码:

 task copy(type: Copy, group: "Custom", description: "Copies sources to the dest directory") {
 from "src"
 into "dest"
 }

kotlin代码:

tasks.create<Copy>("copy") {
 description = "Copies sources to the dest directory"
 group = "Custom"
 from("src")
 into("dest")
}

group 和 description 是自定义的任意值。现在让我们执行这个 task

 ? ./gradlew copy
 > Task :copy
 BUILD SUCCESSFUL in 0s
 1 actionable task: 1 executed

再一次 ls 我们就可以看见 gradle 为我们创建了一个新的 dest 目录并且将 文件复制进去。

Gradle Task

在Gradle中,有两个基本概念:项目和任务。

  • 项目是指我们的构建产物(比如Jar包)或实施产物(将应用程序部署到生产环境)一个项目包含一个或多个任务。
  • 任务是指不可分的最小工作单元,执行构建工作(比如编译项目或执行测试)。

在项目目录中的 build.gradle 指定了一个项目和它的任务。

Task执行顺序

任务可能依赖于其他任务,或者可能被安排为始终在另一个任务之后运行。

 project('projectA') {
 task taskX(dependsOn: ':projectB:taskY') {
 doLast {
 println 'taskX'
 }
 }
 }
 project('projectB') {
 task taskY {
 doLast {
 println 'taskY'
 }
 }
 }
> gradle -q taskX
taskY
taskX // taskx 在 y 之后

我们可以用 dependsOn 让我们的 Task 有顺序的运行起来。

Gradle插件

看到这里,如果每一件事情我们都需要写 Task 岂不是会累死,而且很多功能是可以被复用的,所以Gradle 提供一个 插件 功能,Gradle 默认就内置了大量的插件,比如在 base 中有一系列的功能。

groovy代码:

 plugins {
 id "base"
 }

kotlin代码:

plugins {
 id("base")
}

这个时候我们就可以利用一些额外的 Task,举个例子,我们要把一个目录中的东西都打成一个 ZIP 压缩包。

groovy代码:

task zip(type: Zip, group: "Archive", description: "Archives sources in a zip file") {
 from "src"
 setArchiveName "basic-demo-1.0.zip"
}

kotlin代码:

 tasks.create<Zip>("zip") {
 description = "Archives sources in a zip file"
 group = "Archive"
 from("src")
 setArchiveName("basic-demo-1.0.zip")
 }

Gradle 的设计理念是

  • 在项目中添加新任务
  • 为新加入的任务提供默认配置,这个默认配置会在项目中注入新的约定(如源文件位置)。
  • 加入新的属性,可以覆盖插件的默认配置属性。
  • 为项目加入新的依赖。

Gradle Java

Gradle 内置了 Java 插件,Java插件将Java编译以及测试和捆绑功能添加到项目中。它是许多其他Gradle插件的基础。如果我们需要使用 Java 插件 修改 build.gradle

 plugins {
 id 'java'
 }

一旦导入了 Java 插件,就会有一系列的默认的配置值,并且会导入大量的 Task。

我们从这些 Task 名字就可以看出来他们分别作作了, 和其他的设计理念类型,在 Task 也会嵌入一些生命周期,其实原理也就是我们之前看的执行顺序。

Gradle依赖管理

先盗取一张官方的图。

和 Maven 类似,Gradle 也会将依赖缓冲在本地中,方便在无网的环境使用,和依赖管理相关的有两个参数,举个例子。

 repositories {
 mavenCentral() // 定义仓库
 }
 dependencies {
 compile 'org.springframework:spring-web:5.0.2.RELEASE' // 定义依赖
 }

Gradle支持以下仓库格式:

  • Ivy仓库
  • Maven仓库
  • Flat directory仓库

lvy仓库

我们可以通过URL地址或本地文件系统地址,将Ivy仓库加入到我们的构建中。

repositories {
 ivy {
 url "http://ivy.petrikainulainen.net/repo"
 }
}
//或者是本地
repositories {
 ivy { 
 url "../ivy-repo"
 }
}

Maven仓库

repositories {
 maven {
 url "http://maven.petrikainulainen.net/repo"
 }
}

在加入Maven仓库时,Gradle提供了三种“别名”供我们使用,它们分别是

  • mavenCentral()别名,表示依赖是从Central Maven 2 仓库中获取的。
  • jcenter()别名,表示依赖是从Bintary’s JCenter Maven 仓库中获取的。
  • mavenLocal()别名,表示依赖是从本地的Maven仓库中获取的。

Flat Directory仓库

repositories {
 flatDir {
 dirs 'lib'
 }
}
//多个仓库
repositories {
 flatDir {
 dirs 'libA', 'libB'
 }
}

依赖管理

在配置完项目仓库后,我们可以声明其中的依赖,首先 Java 插件指定了若干依赖配置项

  • compile 配置项中的依赖是依赖必须的。
  • runtime 配置项中包含的依赖在运行时是必须的。
  • testCompile 配置项中包含的依赖在编译项目的测试代码时是必须的。
  • testRuntime 配置项中包含的依赖在运行测试代码时是必须的。

在 Gradle 最新版本中更是增加

  • implementation 配置项中的实现类
  • api 配置项中的暴露API
 dependencies {
 api 'commons-httpclient:commons-httpclient:3.1'
 implementation 'org.apache.commons:commons-lang3:3.5'
 }

声明项目依赖

最普遍的依赖称为外部依赖,这些依赖存放在外部仓库中。一个外部依赖可以由以下属性指定:

  • group属性指定依赖的分组(在Maven中,就是groupId)
  • name属性指定依赖的名称(在Maven中,就是artifactId)
  • version属性指定外部依赖的版本(在Maven中,就是version)
 dependencies {
 compile group: 'foo', name: 'foo', version: '0.1'
 }
 // 我们也可以合并到一起去
 dependencies {
 compile 'foo:foo:0.1'
 }

声明项目文件依赖

我们如何依赖本地的一些 jar 呢,正确的操作是如下

 dependencies {
 compile files('libs/commons-lang.jar', 'libs/log4j.jar')
 }

声明依赖排除项目

我们都知道在 Maven中我们有

 <dependency>
 <groupId>sample.ProjectB</groupId>
 <artifactId>Project-B</artifactId>
 <version>1.0-SNAPSHOT</version>
 <exclusions>
 <exclusion>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 </exclusion>
 </exclusions>
 </dependency>

而在 Gradle 中,我们可以这么做。

compile('com.example.m:m:1.0') {
 exclude group: 'org.unwanted', module: 'x 
}

Gradle与Kotlin

我们想要在 gradle 中增加 kotlin 非常的简单,仅仅需要在 build.gradle 增加

 plugins {
 id "org.jetbrains.kotlin.jvm" version "x.x.xx" // 增加插件
 }
 dependencies {
 compile "org.jetbrains.kotlin:kotlin-stdlib:x.xx.xx" // 增加依赖
 }

大功告成,对了,默认的 Kotlin 的源码路径是 src/main/kotlin, 测试源码是 src/text/kotlin 如果需要修改可以使用

 sourceSets {
 main.kotlin.srcDirs += 'src/main/myKotlin'
 main.java.srcDirs += 'src/main/myJava'
 }


其他

Gradle Wrapper

Gradle Wrapper 做了三件事情

  • 解析参数传入 gradlew
  • 安装正确的 Gradle 版本
  • 调用 Gradle 执行命令

Ops,Gradle Wrapper 为什么还需要安装 Gradle,我们在用 Maven 都知道,我们需要自己先安装好一个 Maven版本,因为 Maven 发展多年,现在已经稳定,已经不存在很多个版本并存的现状了,但是我们依然需要去在每个机器上去安装,那我什么我们不能在自己的 构建脚本 中就指定我们的构建工具呢?所以我们在 wrapper/gradle-wrapper.properties 中就可以发现 distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip 这里也就是定义了我们的gradle所使用的版本。

Gradle In Real World

 // 定义一堆基础插件
 apply plugin: 'java'
 apply plugin: 'maven'
 apply plugin: "jacoco"
 apply plugin: 'checkstyle'
 apply plugin: 'pmd'
 apply plugin: 'findbugs'
 apply plugin: 'eclipse'
 apply plugin: 'idea'
 // 定义项目属性
 group = 'Common'
 version = '1.0.0'
 description = """Giant common library"""
 // 定义依赖仓库
 repositories {
 mavenCentral()
 }
 // 额外增加source path
 sourceSets {
 main {
 resources {
 srcDir "src/main/profiles/${profile}"
 }
 }
 }
 // project依赖
 dependencies {
 compile 'ch.qos.logback:logback-core:1.0.13'
 compile 'ch.qos.logback:logback-classic:1.0.13'
 compile 'ch.qos.logback:logback-access:1.0.13'
 compile 'commons-io:commons-io:2.0.1'
 compile 'commons-lang:commons-lang:2.6'
 compile 'joda-time:joda-time:1.6.2'
 compile 'org.testng:testng:6.8.7'
 compile 'com.googlecode.jmockit:jmockit:1.5'
 ...
 }
 // task配置
 checkstyle {
 ignoreFailures = true
 sourceSets = [sourceSets.main]
 }
 findbugs {
 ignoreFailures = true
 sourceSets = [sourceSets.main]
 }
 pmd {
 ruleSets = ["basic", "braces", "design"]
 ignoreFailures = true
 sourceSets = [sourceSets.main]
 }
 jacocoTestReport {
 reports {
 xml.enabled true
 html.enabled true
 csv.enabled false
 }
 sourceSets sourceSets.main
 }
 tasks.withType(Compile) {
 options.encoding = "UTF-8"
 }
 test {
 useTestNG()
 jacoco {
 excludes = ["org.*"]
 }
 }

Gradle常用指令

枚列所有可用任务

? gradle tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Archive tasks
-------------
zip - Archives sources in a zip file
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
clean - Deletes the build directory.

构建配置属性

? gradle properties

显示构建详情

在 build.gradle 设置

logging.level = LogLevel.DEBUG

或者在运行的

? gradle build --stacktrace 

参考资料&推荐文档

  • Gradle入门教程(http://blog.jobbole.com/71999/)
  • Gradle介绍(https://www.jianshu.com/p/00d5469e25e7)
  • 官方教材(https://guides.gradle.org/creating-new-gradle-builds/)

-END-

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码