基本构建块
每个 Gradle 构建都包含三个基本概念:project、task 和 property。 每个构建包含至少一个 project、一个或多个 task。project 和 task 暴露的属性可以用来控制构建。 Gradle 的核心组件直接的依赖关系如下:
在多项目构建中,一个 project 可以依赖于其他的 project 。在同一个 project 中一个 task 可以依赖一个或多个 task。
Project
org.gradle.api.Project
是主要的与 Gradle 构建文件交换的接口,提供了 Gralde 所有特征的编程访问方式(例如tTask的创建以及依赖的管理)。在调用对应API时无需使用 project 变量,因为 Gradle 会默认你使用的是 Project 的实例,
一个 Project
可以创建新的 Task
,添加依赖关系和配置,并应用插件和其他的构建脚本。
生命周期
“build.gradle” 文件与Project
实例是一一对应的。在构建初始化时,Gradle 为每个参与到构建过程的项目都创建了一个 Project
对象,操作如下:
- 为构建过程创建一个
org.gradle.api.initialization.Settings
实例 - 检查
settings.gradle
脚本,如果存在,这对上面创建的Settings
实例进行相应的配置 - 使用
Settings
实例作为配置信息创建Project
层次的实例 - 最后,循环检擦每个相关的项目,如果存在”build.gradle”文件,则根据该文件对项目对应的
Project
对象进行配置。项目的检查是横向进行的,这样一个项目总是会在其子项目之前进行检测、配置。这个顺序可以通过调用evaluationDependsOnChildren()
进行修改、或者通过evaluationDependsOn(String)
方法添加一个明确的检查依赖关系
Tasks(任务)
一个项目基本上是一个Task
对象的集合。每个Task
的执行一块儿基本的工作,如编译类文件,或运行单元测试,或压缩war文件。我们可以通过实现org.gradle.api.task.TaskContainer
接口的类的名为create
的方法(该方法是一个多重载的方法)来添加Task
,例如TaskContainer.create(String)
,还可以使用TaskContainer
中的一些方法来查找已经存在的Task
,例如TaskCollection.getByName(String)
。
在第一个 Gradle 脚本及简单命令 的学习中我们对 Task 就已经有过接触,并且使用过其中一些较为重要的功能:任务动作(task action)以及任务依赖(task dependency)。
Task action(任务动作)
任务动作定义了一个任务执行时的最小工作单元,可以是简单的输出,也可以是诸如编译等较为复杂的工作。例如第一个 Gradle 脚本及简单命令 中的:
代码语言:javascript复制task helloworldSort {
//doLast 就是 Task 中的一个任务动作
doLast{
print 'Hello world!'
}
}
Task dependency(任务依赖)
但一个任务运行时需要先运行另一个任务,这两个任务间就需要有任务依赖。例如第一个 Gradle 脚本及简单命令 中的:
代码语言:javascript复制// 任务依赖
yayGradle0.dependsOn startSession
/* 任务执行的顺序 startSession -> yayGradle0 -> yayGradle1 -> yayGradle2 -> groupTherapy */
// 任务依赖
task groupTherapy(dependsOn: yayGradle2) << {
println 'groupTherapy'
}
以上就是任务依赖的两种使用方法。
下面是 Task
的API:
Dependencies(依赖项)
一个项目为了完成构建工作,通常会有数个依赖。此外,项目通常会产生一系列的其他项目可以使用的工件。这些依赖项按配置分组,可以从资料库检出或上传自己的依赖项到资料库。getConfigurations()
方法返回的ConfigurationContainer
用于管理配置相关信息。 getDependencies()
方法返回的DependencyHandler
用来管理依赖项相关信息。 ArtifactHandler.getArtifacts()
方法返回管理工件相关信息。 getRepositories()
方法返回的RepositoryHandler
用来管理存储库相关信息。
多项目构建(Multi-project Builds)
多项目会被排成的一个层次结构。一个项目有一个名称以及能够唯一标识该层次结构中的完全限定的路径。
插件(Plugins)
插件可以用于模块化 以及重用项目配置。可以使用PluginAware.apply(java.util.Map)
方法,应用插件或通过使用插件脚本块。
plugins {
id "org.company.myplugin" version "1.3"
}
以上就是一个简单的插件脚本块。
属性(Properties)
Gradle 执行项目的构建文件来配置对应的Project
实例。任何属性或您的脚本使用的方法是通过授予关联的Project
对象来实现的。这意味着,你可以在您的脚本直接使用Project
接口上的任何方法和属性。
例如︰
defaultTasks('some-task') // Project.defaultTasks()
reportsDir = file('reports') // Project.file() and the Java Plugin
您也可以访问使用该属性的实例。在某些情况下,这可以使脚本更清晰。例如,您可以使用project.name
来访问该项目的名称。
一个项目有 6个属性 “范围”用于搜索属性。您可以通过构建文件中的名称或通过调用项目的property(String)
方法访问这些属性。5个属性“范围”是:
1. Project
对象本身。此范围包括Project
实现类声明的属性的getter和setter。例如,getRootProject()
可作为rootProject
的属性访问方式。此范围的属性是可读或可写的,存在对相应 getter 和 setter 方法。
- 项目的额外属性。每个项目都维护一个额外属性的映射,可以包含任意
名称 - >值
对。一旦定义,该范围的属性是可读和可写的。有关详细信息,请参阅其他属性。 - 通过添加插件将扩展添加到项目中。每个扩展都是只读属性,与扩展具有相同的名称。
- 通过插件将约定属性添加到项目中。插件可以通过项目的
Convention
对象向项目添加属性和方法。此范围的属性可以是可读或可写的,这取决于约定对象。 - 项目的任务。可以通过使用其名称作为属性名称来访问任务。此范围的属性是只读的。例如,调用的任务
compile
可作为compile
属性访问。 - 继承自项目父级的额外属性和惯例属性,递归到根项目。此作用域的属性为只读。
当读取属性时,项目按顺序搜索上述范围,并从其找到属性的第一个范围返回值。如果未找到,将抛出异常。查看
property(String)
更多详细信息。 编写属性时,项目按顺序搜索上述范围,并将其属性设置在第一个作用域中,该属性位于其中。如果未找到,将抛出异常。查看setProperty(String, Object)
更多详细信息。
额外属性
所有额外的属性必须通过“ext”命名空间进行定义。一旦额外的属性被定义,它可以直接在所有的对象(在下面的情况下分别是项目,任务和子项目)可用,并且可以被读取和更新。只需要在最初宣布通过命名空间来完成。
代码语言:javascript复制project.ext.prop1 = "foo"
task doStuff {
ext.prop2 = "bar"
}
subprojects { ext.${prop3} = false }
通过“ext”或通过拥有的对象来读取额外的属性。
代码语言:javascript复制ext.isSnapshot = version.endsWith("-SNAPSHOT")
if (isSnapshot) {
// do snapshot stuff
}
动态方法
一个项目有5种方法“范围”,它搜索方法:
1. Project
对象本身。
2. 构建文件。该项目搜索在构建文件中声明的匹配方法。
3. 插件添加到项目的扩展。每个扩展可用作接受闭包或Action作为参数的方法。
4. 通过插件将约定方法添加到项目中。插件可以通过项目的Convention
对象向项目添加属性和方法。
5. 项目的任务。为每个任务添加一个方法,使用任务的名称作为方法名称并获取单个闭包或Action
参数。该方法Task.configure(groovy.lang.Closure)
6. 使用提供的闭包调用关联任务的方法。例如,如果项目有一个被调用的任务compile,那么将添加一个方法,并带有以下签名:void compile(Closure configureClosure)。
7. 父项目的方法,递归到根项目。
8. 项目的属性,其值为闭包。封闭被视为一种方法,并使用提供的参数进行调用。该物业的位置如上所述。
下面是 Project
的API:
下面是 PluginAware
的API: