配置子项目
Gradle为每个build.gradle都会创建一个相应的Project领域对象,在编写Gradle脚本时,我们实际上是在操作诸如Project这样的Gradle领域对象。在多Project的项目中,我们会操作多个Project领域对象。Gradle提供了强大的多Project构建支持。
要创建多Project的Gradle项目,我们首先需要在根(Root)Project中加入名为settings.gradle
的配置文件。settings.gradle
会在 初始化阶段 读取执行,所以我们也可以将一些需要在初始化阶段执行的逻辑放到此处。
该文件应该包含各个子Project的名称。比如,我们有一个根Project名为root-project
,它包含有两个子Project,名字分别为sub-project1
和sub-project2
,此时对应的文件目录结构如下:
root-project/
sub-project1/
build.gradle
sub-project2/
build.gradle
build.gradle
settings.gradle
root-project本身也有自己的build.gradle
文件,同时它还拥有settings.gradle
文件位于和build.gradle
相同的目录下。此外,两个子Project也拥有他们自己的build.gradle
文件。
要将sub-project1
和sub-project2
加入到root-project
的子Project中,我们需要在settings.gradle
中加入:
include 'sub-project1', 'sub-project2'
多项目构建总是需要指定一个树根,树中的每一个节点代表一个项目,每一个project对象都指定有一个表示在树中位置的路径。上面例子中把project的路径作为了include方法的参数,譬如上面的sub-project1
就指定了物理路径的sub-project1
。
当然了,设置文件中创建的多项目树其实是由项目描述符来描述的,我们可以在设置文件中随时修改这些描述符。现在为root-project
多添加了一个子Project:sub-project3
,但是sub-project3
并不在root-project目录下,而是和root-project目录同级,应该怎么在settings.gradle
表述呢?
sub-project3/
build.gradle
root-project/
sub-project1/
build.gradle
sub-project2/
build.gradle
build.gradle
settings.gradle
表述方式如下:
rootProject.name = 'root-project'
include 'sub-project1'
include 'sub-project2'
include 'sub-project3'
project(':sub-project3').projectDir = file("$rootDir/../sub-project3")
$rootDir指的是root-project项目所在的目录,至于..我觉得是说从rootDir开始找,一层层找,一直到找到sub-project3为止。
共享配置
在大型Java项目中,子项目之间必然具有相同的配置项。我们在编写代码时,要追求代码重用和代码整洁;而在编写Gradle脚本时,同样需要保持代码重用和代码整洁。Gradle 提供了不同的方式使不同的项目能够共享配置。
【allprojects】
allprojects是根Project的一个属性,在Gradle中,我们可以通过根Project的allprojects()方法将配置一次性地应用于所有的Project,当然也包括定义Task。比如:
allprojects {
apply plugin: 'idea'
task allTask << {
println project.name
}
}
以上Gradle脚本将闭包中的代码应用在所有的Project中,包括root-project本身。我们首先将应用了idea Plugin用于生成IntelliJ工程,其次我们定义了名为allTask的Task,该Task应用于每个Project,作用是输出各个Project的名称。执行“gradle allTask”,命令行输出如下:
:allTask
root-project
:sub-project1:allTask
sub-project1
:sub-project2:allTask
sub-project2
我们看到,该allTask对于每个Project都执行了一次,在执行时输出了当前Project的名称。
【subprojects】
subprojects和allprojects一样,也是父Project的一个属性,在父项目的build.gradle脚本里,但subprojects()方法用于配置所有的子Project(不包含根Project)。
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
ext {
guavaVersion = ’14.0.1’
junitVersion = ‘4.10’
}
dependencies {
compile(
“com.google.guava:guava:${guavaVersion}”
)
testCompile(
“junit:junit:${junitVersion}”
)
}
task subTask << {
println project.name
}
}
执行“gradle subTask”,命令行输出如下:
:sub-project1:subTask
sub-project1
:sub-project2:subTask
sub-project2
此时的输出中不再包含root-project的名字。
此外,这里还在ext里配置依赖包的版本,方便以后升级依赖的版本。
【configure】
在项目中,并不是所有的子项目都会具有相同的配置,但是会有部分子项目具有相同的配置。Gradle提供的 configure 属性块可以让我们根据模块名称引入特定插件。:
configure(allprojects.findAll { it.name.startsWith('sub') }) {
subTask << {
println 'this is a sub project'
}
}
在上面的代码中,我们先找到所有Project中名字以“sub”开头的Project,然后再对这些Project进行配置,在配置中,我们向这些Project的subTask中加入了一条额外的打印语句。
此时如果再执行“gradle subTask”,命令行输出如下:
:sub-project1:subTask
sub-project1
this is a sub project
:sub-project2:subTask
sub-project2
this is a sub project
或者我们可以通过ext定义一个变量再传入到configure中:
ext.subProjects = allprojects.findAll { it.name.startsWith('sub') }
configure(subProjects) {
apply plugin: 'war'
}
独享配置
到此为止,我们所有的Task定义工作都是在root-project中进行的,而sub-project1和sub-project2中的build.gradle文件依然什么都没有。事实上,我们可以将所有对子Project的配置均放在根Project中进行。在上面的例子中,我们通过allprojects()和subprojects()将所有的子Project都包含在了配置之内,其实我们还可以对单个Project进行单独配置。比如,在root-project的build.gradle中加入:
project(':sub-project1') {
task forProject1 << {
println 'for project 1'
}
}
以上脚本向sub-project1中加入了名为forProject1的Task,在执行“gradle forProject1”时,终端输出如下:
:sub-project1:forProject1
for project 1
注意这里子项目名字前面有一个冒号(:)。 通过这种方式,指定对应的子项目,并对其进行配置。
(2)我们还可以在每个子项目的目录里建立自己的构建脚本。在上例中,可以在子项目core目录下为其建立一个build.gradle文件,并在该构建脚本中配置core子项目所需的所有配置。例如,在该build.gradle文件中添加如下配置:
ext{
hibernateVersion = ‘4.2.1.Final’
}
dependencies {
compile “org.hibernate:hibernate-core:${hibernateVersion}”
}