1. gradle简介
Java世界中主要有三大构建工具:Ant、Maven和Gradle。经过几年的发展,Ant几乎销声匿迹、Maven也日薄西山,而Gradle的发展则如日中天。
1.1. ANT
ANT是最早的构建工具,其主要基于IDEA,在2000年的时候最流行java构建工具,虽然对工程构建过程中的过程控制特别好,也比较灵活,但是它的XML脚本编写格式让XML文件特别大。
1.2. Maven
Maven主要是用来填补Ant的坑的,Maven第一次支持了从网络上下载的功能,仍然采用xml作为配置文件格式,其主要专注的是依赖管理,主要好处是它的生命周期。虽然接连的多个项目生命周期相同,这是以灵活性为代价的。 Maven也面临着依赖管理的一些问题。它不会在同一库版本之间处理好矛盾,复杂的定制构建脚本实际上Maven比ANT更难写。
1.3. Gradle
Grale是一个自动化的构建工具,Gradle属于结合以上两个的优点,它继承了Ant的灵活和Maven的生命周期管理,它最后被google作为了Android御用管理工具。它最大的区别是不用XML作为配置文件格式,采用了DSL格式,使得脚本更加简洁。Gradle引入了基于Groovy语言的DSL语法来代替XML配置,因此它的配置文件是一个Groovy文件。
2. gradle功能特性
- 基于声明的构建和基于约定的构建
Gradle 的核心在于基于 Groovy 的丰富而可扩展的域描述语言(DSL)。 Groovy 通过声明性的语言元素将基于声明的构建推向下层,你可以按你想要的方式进行组合。 这些元素同样也为支持 Java, Groovy,OSGi,Web 和 Scala 项目提供了基于约定的构建。 并且,这种声明性的语言是可以扩展的。你可以添加新的或增强现有的语言元素。 因此,它提供了简明、可维护和易理解的构建。
- 为以依赖为基础的编程方式提供语言支持
声明性语言优点在于通用任务图,你可以将其充分利用在构建中. 它提供了最大限度的灵活性,以让 Gradle 适应你的特殊需求。
- 构建结构化
Gradle 的灵活和丰富性最终能够支持在你的构建中应用通用的设计模式。 例如,它可以很容易地将你的构建拆分为多个可重用的模块,最后再进行组装,但不要强制地进行模块的拆分。 不要把原本在一起的东西强行分开(比如在你的项目结构里),从而避免让你的构建变成一场噩梦。 最后,你可以创建一个结构良好,易于维护,易于理解的构建。
- 深度 API
Gradle 允许你在构建执行的整个生命周期,对它的核心配置及执行行为进行监视并自定义。
- Gradle 的扩展
Gradle 有非常良好的扩展性。 从简单的单项目构建,到庞大的多项目构建,它都能显著地提升你的效率。 这才是真正的结构化构建。通过最先进的增量构建功能,它可以解决许多大型企业所面临的性能瓶颈问题。
- 多项目构建
Gradle 对多项目构建的支持非常出色。项目依赖是首先需要考虑的问题。 我们允许你在多项目构建当中对项目依赖关系进行建模,因为它们才是你真正的问题域。 Gradle 遵守你的布局。
Gradle 提供了局部构建的功能。 如果你在构建一个单独的子项目,Gradle 也会帮你构建它所依赖的所有子项目。 你也可以选择重新构建依赖于特定子项目的子项目。 这种增量构建将使得在大型构建任务中省下大量时间。
- 多种方式管理依赖
不同的团队喜欢用不同的方式来管理他们的外部依赖。 从 Maven 和 Ivy 的远程仓库的传递依赖管理,到本地文件系统的 jar 包或目录,Gradle 对所有的管理策略都提供了方便的支持。
- Gradle 是第一个构建集成工具
Ant tasks 是最重要的。而更有趣的是,Ant projects 也是最重要的。 Gradle 对任意的 Ant 项目提供了深度导入,并在运行时将 Ant 目标(target)转换为原生的 Gradle 任务(task)。 你可以从 Gradle 上依赖它们(Ant targets),增强它们,甚至在你的 build.xml 上定义对 Gradle tasks 的依赖。Gradle 为属性、路径等等提供了同样的整合。
Gradle 完全支持用于发布或检索依赖的 Maven 或 Ivy 仓库。 Gradle 同样提供了一个转换器,用于将一个 Maven pom.xml 文件转换为一个 Gradle 脚本。Maven 项目的运行时导入的功能将很快会有。
- 易于移植
Gradle 能适应你已有的任何结构。因此,你总可以在你构建项目的同一个分支当中开发你的 Gradle 构建脚本,并且它们能够并行进行。 我们通常建议编写测试,以保证生成的文件是一样的。 这种移植方式会尽可能的可靠和减少破坏性。这也是重构的最佳做法。
- Groovy
Gradle 的构建脚本是采用 Groovy 写的,而不是用 XML。 但与其他方法不同,它并不只是展示了由一种动态语言编写的原始脚本的强大。 那样将导致维护构建变得很困难。 Gradle 的整体设计是面向被作为一门语言,而不是一个僵化的框架。 并且 Groovy 是我们允许你通过抽象的 Gradle 描述你个人的 story 的黏合剂。 Gradle 提供了一些标准通用的 story。这是我们相比其他声明性构建系统的主要特点。 我们的 Groovy 支持也不是简单的糖衣层,整个 Gradle 的 API 都是完全 groovy 化的。只有通过 Groovy才能去运用它并对它提高效率。
- The Gradle wrapper
Gradle Wrapper 允许你在没有安装 Gradle 的机器上执行 Gradle 构建。 这一点是非常有用的。比如对一些持续集成服务来说。 它对一个开源项目保持低门槛构建也是非常有用的。 Wrapper 对企业来说也很有用,它使得对客户端计算机零配置。 它强制使用指定的版本,以减少兼容支持问题。
- 自由和开源
Gradle 是一个开源项目,并遵循 ASL 许可。
3. gradle安装
3.1. windows安装
- 进入gradle官网:https://gradle.org,点击【Install Gradle】
- 进入页面后,可以看到installing manually手动安装,有binary-only和complete两种安装包,complete完整一些,包括文档和相应的源。
- 这里我选择了binary-only下载,下载并解压到自己想要的目录,这里我解压到我的D目录:D:\
- 添加环境变量GRADLE_HOME和path,如下所示
GRADLE_HOME:D:\F:\TEST\gradle-6.1-bin\gradle-6.1 path:%GRADLE_HOME%\bin
- 添加环境变量完成后,打开cmd命令模式,输入gradle -v,若展示gradle基本信息,则表明安装成功
3.2. gradle目录简介
gradle的目录其实与maven的目录结构是一致的,大体如下所示:
其中:
- build.gradle 用于配置当前项目的Gradle构建脚本
- gradle-wrapper.jar Gradle Wrapper可执行JAR
- gradle-wrapper.properties Gradle Wrapper配置属性
- gradlew 基于Unix的系统的Gradle Wrapper脚本
- gradlew.bat 适用于Windows的Gradle Wrapper脚本
- settings.gradle 用于配置Gradle构建的Gradle设置脚本
3.3. 新建gradle项目
3.3.1. 第一种方式
直接使用命令的方式进行创建。
- 创建一个空文件夹并进入目录
- 依次输入如下命令:gradle init
- 选择项目的类型
- 选择要使用的语言
- 选择测试框架
- 选择脚本编写的语言
- 输入项目名称、包名,默认是我们刚才进入的文件夹名称 ,即可。
3.3.2. 第二种方式
使用工具直接创建,在IEDA中配置gradle后创建项目。
- File=>Settings=>Build,Execution,Deployment=>Builid Tools=>Gradle路径下配置如下:
- 然后新建一个gradle项目
- 然后填入指定的groupId和artifactId后完成创建,目录如下。
4. gradle构建基础
gradle构建中的两个基本概念是项目(project)和任务(task),每个构建至少包含一个项目,项目中包含一个或多个任务。在多项目构建中,一个项目可以依赖于其他项目;类似的,任务可以形成一个依赖关系图来确保他们的执行顺序。
4.1. gradle构建生命周期
Gradle的构建生命周期分为初始化,配置,执行三个阶段。
4.1.1. 初始化阶段
初始化阶段主要是读取settings.gradle 文件,用于确定哪些项目参与构建,并创建Project实例;如多个项目构建时,通常setting.gradle内容如下:
include "projectA","projectB","projectC" //表示参与构建的项目有projectA,projectB,projectC
4.1.2. 配置阶段
配置阶段主要是为每个项目的build.gradle文件配置project对象;主要是生成task的依赖关系跟执行图。
4.1.3. 执行阶段
执行阶段主要是根据gradle命令和传入的参数创建并执行任务。
4.2. gradle任务
Gradle构建脚本描述一个或多个项目。每个项目都由不同的任务组成。任务是构建执行的一项工作,主要包括任务动作和任务依赖,任务动作定义了一个最小的工作单元,可以定义依赖,动作序列和执行条件;Gradle保证这些任务按其依赖项的顺序执行,并且每个任务只执行一次。这些任务可以抽象成一个有向无环图。Gradle会在执行任务之前构建完整的依赖关系图,这就是Gradle的核心思想。
4.2.1. 定义任务
任务是构建脚本build.gradle中的关键字,任务的定义模式大体如下所示:
task testTask{
doLast {
println ‘I am a tester‘
}
}
#doLast 语句可以使用快捷方式(表示符号 <<)来简化此任务
#上述语句等同于:
task testTask << {
println ‘I am a tester‘
}
如下,在终端中输入如下命令执行task
gradle -q testTask
4.2.2. 任务依赖
要将一个任务依赖另一个任务,在开始这个任务之前,先完成依赖的任务。 每个任务都使用任务名称进行区分。
任务的依赖第一种填写方式,我们可以直接在定义任务是指定需要依赖的任务,其中需要注意如下两点:
- 被依赖的任务可以定义在之前或者之后
- 如果被依赖的任务定义在之后,也叫做延迟依赖,延迟依赖下,被引用的的任务名需要加入引号,所以通常我们把引号加上就好了
task testTask {
doLast {
println ‘I am a tester‘
}
}
//被依赖的任务可以定义在之前或者之后
//如果被依赖的任务定义在之后,也叫做延迟依赖,
//延迟依赖下,被引用的的任务名需要加入引号,所以通常我们把引号加上就好了
task testDepend(dependsOn:‘testTask‘) {
doLast {
println ‘I do test job‘
}
}
如下,在终端中输入如下命令执行任务:
gradle -q testDepend
依赖的第二种填写方式,分别编写完任务后,在末尾写入依赖语句:
task testTask {
doLast {
println ‘I am a tester‘
}
}
task testDepend {
doLast {
println ‘I do test job‘
}
}
testDepend.dependsOn testTask
如下,在终端中输入如下命令执行任务:
gradle -q testDepend
4.2.3. 定位任务
如果要查找在构建文件中定义的任务,则必须使用相应的标准项目属性。这意味着每个任务都可以作为项目的属性,使用任务名称作为属性名称。
如下在build.gradle中定义了一个任务xiong,那么我们可以通过如下方式查找任务
task xiong
println xiong.name
println project.xiong.name
如下,在终端中输入如下命令执行任务:
gradle -q xiong
当然我们也可以由其任务集合(tasks)来查找。要引用另一个项目中的任务,应该使用项目路径作为相应任务名称的前缀。
task xiong
println tasks.xiong.name
println tasks[‘xiong‘].name
如下,在终端中输入如下命令执行任务:
gradle -q xiong
4.3. gradle依赖管理
Gradle构建脚本定义了构建项目的过程; 每个项目包含一些依赖项和一些发表项。依赖性意味着支持构建项目所需要的东西,比如构建时需要的jar包等。发布表示项目的结果,如测试类文件和构建文件,如war文件。
4.3.1. 依赖管理
如下是一个依赖管理简要图,其流程主要为:
- 依赖管理器读取到配置文件build.gradle中需要的依赖项时
- 先查看缓存或者本地没有指定的依赖项
- 如果没有,则通过网络去指定的远程仓库进行下载
- 下载后的依赖将保存在本地仓库
- 如果依赖多次使用,则会存储在依赖缓存中
传递依赖
B依赖A,如果C依赖B,那么C依赖A。
几乎所有的基于JVM的软件项目都需要依赖外部类库来重用现有的功能。自动化的依赖管理可以明确依赖的版本,可以解决因传递性依赖带来的版本冲突。
版本冲突
如下hibermate-core-3.6.3.Final.jar依赖的hibermate-core-3.2.0.Final.jar包中依赖了slf4i-api-1.5.8.jar,所以按传递依赖的性质,hibermate-core-3.6.3.Final.jar会依赖slf4i-api-1.5.8.jar
而hibermate-core-3.6.3.Final.jar本身又依赖了slf4i-api-1.6.1.jar,所以会导致版本冲突
但是因为gradle默认会依赖最高版本的jar包,所以gradle默认是不会出现版本冲突的,
4.3.2. 声明依赖关系
在gradle中,一个group、name、version确定一个唯一的jar包,如在build.gradle文件中配置如下依赖,定义了两个依赖项,一个是Hibernate core 3.6.7,第二个是Junit 4.0和更高版本。
- Hibernate core 3.6.7用于编译时需要依赖的项
- Junit 4.0和更高版本用于测试编译时需要依赖的项
dependencies {
compile group: ‘org.hibernate‘, name: ‘hibernate-core‘, version: ‘3.6.7.Final‘
testCompile group: ‘junit‘, name: ‘junit‘, version: ‘4.+‘
}
4.3.3. 依赖阶段配置
依赖关系配置只是定义了一组依赖关系,然后我们根据指定的依赖声明从Web下载外部依赖关系。如下是依赖阶段不同的标准配置:
- compile:编译------编译项目的生产源所需的依赖关系。
- runtime:运行时------运行时生产类所需的依赖关系。 默认情况下,还包括编译时依赖项。
- testCompile:测试编译------编译项目测试源所需的依赖项。 默认情况下,它包括编译的产生的类和编译时的依赖。
- testRuntime:测试运行时------运行测试所需的依赖关系。 默认情况下,它包括运行时和测试编译依赖项。
4.3.4. 外部依赖
依赖的类型有很多种,其中有一种类型称之为外部依赖。这种依赖由外部构建或者储存在不同的仓库中,例如 Maven 中央仓库或 Ivy 仓库中抑或是本地文件系统的某个目录中。
如下就定义了一个外部依赖,在进行构建时会从仓库中去查找该依赖:
dependencies {
compile group: ‘org.hibernate‘, name: ‘hibernate-core‘, version: ‘3.6.7.Final‘
}
外部依赖包含 group,name 和 version 几个属性。根据选取仓库的不同,group 和 version 也可能是可选的。
当然,也有一种更加简洁的方式来声明外部依赖。采用:将三个属性拼接在一起即可。"group:name:version"
dependencies {
compile ‘org.hibernate:hibernate-core:3.6.7.Final‘
}
4.3.5. 存储库配置
在添加依赖关系时, Gradle在存储库中查找它们。 存储库只是文件的集合,按group,name和version来组织构造; 默认情况下,Gradle不定义任何存储库,我们必须至少明确地定义一个存储库。如下我们先定义了一个自定义的maven仓库,然后是本地的maven仓库,最后是maven的中央仓库,在查找依赖时依次从上到下进行查找。
repositories {
//自定义maven仓库,也就是maven私服
maven {
url:‘xxxx‘
}
mavenLocal() //本地仓库
mavenCentral() //公共仓库-maven中央仓库
jcenter() //公共仓库-jcenter仓库
}
4.3.6. 多项目构建
在企业项目中,包层次和类关系比较复杂,把代码拆分成模块通常是最佳实践,这选哟清晰的划分功能边界,比如把业务逻辑和数据持久化拆分开来,项目符合高内聚低耦合时,模块化就不安的很容易,这是也是多项目的由来。
4.3.7. 发布文件
依赖管理配置也被用于发布文件我们称之为打包发布或发布。
插件对于打包提供了完美的支持,所以通常而言无需特别告诉 Gradle 需要做什么。但是你需要告诉 Gradle 发布到哪里。这就需要在 uploadArchives 任务中添加一个仓库。
发布到 Maven 仓库你需要 Maven 插件的支持,当我们使用:gradle uploadArchives 命令时,Gradle 构建并上传你的 jar 包,同时产生 pom.xml 一起上传到下方指定的maven仓库。
apply plugin: ‘maven‘
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost/xxx/")
}
}
}
当我们使用:gradle uploadArchives 命令时,Gradle 便会构建并上传你的 jar 包,同时会生成一个 ivy.xml 一起上传到如下指定的ivy仓库:
uploadArchives {
repositories {
ivy {
credentials {
username "username"
password "password"
}
url "http://repo.mycompany.com"
}
}
}
4.4. grale插件
Gradle 在它的核心中有意地提供了一些小但有用的功能,用于在真实世界中的自动化。所有有用的功能,例如以能够编译 Java 代码为例,都是通过插件进行添加的。插件都认为是被应用,通过 Project.apply() 方法来完成。
4.4.1. Java插件
Java 插件向一个项目添加了 Java 编译、 测试和 bundling 的能力。它是很多其他 Gradle 插件的基础服务。
Java 插件定义了两个标准的源集,分别是 main 和 test。main 源集包含你产品的源代码,它们将被编译并组装成一个 JAR 文件。test 源集包含你的单元测试的源代码,它们将被编译并使用 JUnit 或 TestNG 来执行。
在build.grale文件中Java插件的引入如下所示:
apply plugin: ‘java‘
如上是使用短名称的方式,我们也可以使用完整的名称方式:
apply plugin: org.gradle.api.plugins.JavaPlugin
或者
apply plugin: JavaPlugin
同时Java 插件向你的项目添加了大量的任务,具体可参考官网或者地址:
https://www.w3cschool.cn/gradle/q9bp1hum.html
4.4.2. groovy插件
Groovy 的插件继承自 Java 插件并添加了对 Groovy 项目的支持。它可以处理 Groovy 代码,以及混合的 Groovy 和 Java 代码,甚至是纯 Java 代码(尽管我们不一定推荐使用)。该插件支持联合编译,可以任意地混合及匹配 Groovy 和 Java 代码各自的依赖。例如,一个 Groovy 类可以继承自一个 Java 类,而这个 Java 类也可以继承自一个 Groovy 类。这样一来,我们就能够在项目中使用最适合的语言,并且在有需要的情况下用其他的语言重写其中的任何类。
其在build.gradle文件中的添加方法如下:
apply plugin: ‘groovy‘
同样groovy插件也向Project中添加了大量的任务,具体请参考官网或者地址:
https://www.w3cschool.cn/gradle/q9bp1hum.html
4.4.3. war插件
War 的插件继承自 Java 插件并添加了对组装 web 应用程序的 WAR 文件的支持。它禁用了 Java 插件生成默认的 JAR archive,并添加了一个默认的 WAR archive 任务。
apply plugin: ‘war‘
同样war插件也向Project中添加了大量的任务,具体请参考官网或者地址:
https://www.w3cschool.cn/gradle/q9bp1hum.html
4.4.4. jetty插件
Jetty 插件继承自 War 插件,并添加一些任务,这些任务可以让你在构建时部署你的 web 应用程序到一个 Jetty 的 web 嵌入式容器中。
apply plugin: ‘jetty‘
同样jetty插件也向Project中添加了大量的任务,具体请参考官网或者地址:https://www.w3cschool.cn/gradle/xg9o1hu7.html
5. gradle构建命令
序号 |
命令 |
描述 |
1 |
gradle -q taskName1 taskName2 |
-q表示获取构建信息,执行具体的任务,可以指定多个任务 |
2 |
gradle tasks |
列出所有任务列表 |
3 |
gradle build |
Gralde 会编译并执行单元测试,并且将 src/main/* 下面 class 和资源文件打包 |
4 |
gradle build -x taskName |
执行构建命令,并排除taskName任务 |
5 |
gradle build -continue |
默认情况下Gradle将在任何任务失败时立即中止执行。如果我们希望即使发生故障,也可以继续执行,使用-continue |
6 |
gradle clean |
删除 build 目录以及所有构建完成的文件 |
7 |
gradle assemble |
编译并打包 jar 文件,但不会执行单元测试。一些其他插件可能会增强这个任务的功能。例如,如果采用了 War 插件,这个任务便会为你的项目打出 War 包 |
8 |
grale check |
编译并测试代码。一些其他插件也可能会增强这个任务的功能。例如,如果采用了 Code-quality 插件,这个任务会额外执行 Checkstyle |
9 |
gradle -q [projectName] projects |
列出所选项目及其子项目的项目层次结构 |
10 |
gradle –q [projectName] dependencies |
提供所选项目的依赖关系的列表 |
11 |
gradle -q [projectName] properties |
提供所选项目的属性列表 |
12 |
gradle -p projectName -x test build |
多项目中指定需要构建的项目,并排除测试构建 |
原文地址:https://www.cnblogs.com/wendyw/p/12202356.html