配置子項(xiàng)目
Gradle為每個(gè)build.gradle都會(huì)創(chuàng)建一個(gè)相應(yīng)的Project領(lǐng)域?qū)ο?,在編?xiě)Gradle腳本時(shí),我們實(shí)際上是在操作諸如Project這樣的Gradle領(lǐng)域?qū)ο蟆T诙郟roject的項(xiàng)目中,我們會(huì)操作多個(gè)Project領(lǐng)域?qū)ο蟆radle提供了強(qiáng)大的多Project構(gòu)建支持。
要?jiǎng)?chuàng)建多Project的Gradle項(xiàng)目,我們首先需要在根(Root)Project中加入名為settings.gradle的配置文件。settings.gradle會(huì)在 初始化階段 讀取執(zhí)行,所以我們也可以將一些需要在初始化階段執(zhí)行的邏輯放到此處。
該文件應(yīng)該包含各個(gè)子Project的名稱。比如,我們有一個(gè)根Project名為root-project,它包含有兩個(gè)子Project,名字分別為sub-project1和sub-project2,此時(shí)對(duì)應(yīng)的文件目錄結(jié)構(gòu)如下:
root-project/
sub-project1/
build.gradle
sub-project2/
build.gradle
build.gradle
settings.gradle
root-project本身也有自己的build.gradle文件,同時(shí)它還擁有settings.gradle文件位于和build.gradle相同的目錄下。此外,兩個(gè)子Project也擁有他們自己的build.gradle文件。
要將sub-project1和sub-project2加入到root-project的子Project中,我們需要在settings.gradle中加入:
include 'sub-project1', 'sub-project2'
多項(xiàng)目構(gòu)建總是需要指定一個(gè)樹(shù)根,樹(shù)中的每一個(gè)節(jié)點(diǎn)代表一個(gè)項(xiàng)目,每一個(gè)project對(duì)象都指定有一個(gè)表示在樹(shù)中位置的路徑。上面例子中把project的路徑作為了include方法的參數(shù),譬如上面的sub-project1就指定了物理路徑的sub-project1。
當(dāng)然了,設(shè)置文件中創(chuàng)建的多項(xiàng)目樹(shù)其實(shí)是由項(xiàng)目描述符來(lái)描述的,我們可以在設(shè)置文件中隨時(shí)修改這些描述符?,F(xiàn)在為root-project多添加了一個(gè)子Project:sub-project3,但是sub-project3并不在root-project目錄下,而是和root-project目錄同級(jí),應(yīng)該怎么在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項(xiàng)目所在的目錄,至于..我覺(jué)得是說(shuō)從rootDir開(kāi)始找,一層層找,一直到找到sub-project3為止。
共享配置
在大型Java項(xiàng)目中,子項(xiàng)目之間必然具有相同的配置項(xiàng)。我們?cè)诰帉?xiě)代碼時(shí),要追求代碼重用和代碼整潔;而在編寫(xiě)Gradle腳本時(shí),同樣需要保持代碼重用和代碼整潔。Gradle 提供了不同的方式使不同的項(xiàng)目能夠共享配置。
【allprojects】
allprojects是根Project的一個(gè)屬性,在Gradle中,我們可以通過(guò)根Project的allprojects()方法將配置一次性地應(yīng)用于所有的Project,當(dāng)然也包括定義Task。比如:
allprojects {
apply plugin: 'idea'
task allTask << {
println project.name
}
}
以上Gradle腳本將閉包中的代碼應(yīng)用在所有的Project中,包括root-project本身。我們首先將應(yīng)用了idea Plugin用于生成IntelliJ工程,其次我們定義了名為allTask的Task,該Task應(yīng)用于每個(gè)Project,作用是輸出各個(gè)Project的名稱。執(zhí)行“gradle allTask”,命令行輸出如下:
:allTask
root-project
:sub-project1:allTask
sub-project1
:sub-project2:allTask
sub-project2
我們看到,該allTask對(duì)于每個(gè)Project都執(zhí)行了一次,在執(zhí)行時(shí)輸出了當(dāng)前Project的名稱。
【subprojects】
subprojects和allprojects一樣,也是父Project的一個(gè)屬性,在父項(xiàng)目的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
}
}
執(zhí)行“gradle subTask”,命令行輸出如下:
:sub-project1:subTask
sub-project1
:sub-project2:subTask
sub-project2
此時(shí)的輸出中不再包含root-project的名字。
此外,這里還在ext里配置依賴包的版本,方便以后升級(jí)依賴的版本。
【configure】
在項(xiàng)目中,并不是所有的子項(xiàng)目都會(huì)具有相同的配置,但是會(huì)有部分子項(xiàng)目具有相同的配置。Gradle提供的 configure 屬性塊可以讓我們根據(jù)模塊名稱引入特定插件。:
configure(allprojects.findAll { it.name.startsWith('sub') }) {
subTask << {
println 'this is a sub project'
}
}
在上面的代碼中,我們先找到所有Project中名字以“sub”開(kāi)頭的Project,然后再對(duì)這些Project進(jìn)行配置,在配置中,我們向這些Project的subTask中加入了一條額外的打印語(yǔ)句。
此時(shí)如果再執(zhí)行“gradle subTask”,命令行輸出如下:
:sub-project1:subTask
sub-project1
this is a sub project
:sub-project2:subTask
sub-project2
this is a sub project
或者我們可以通過(guò)ext定義一個(gè)變量再傳入到configure中:
ext.subProjects = allprojects.findAll { it.name.startsWith('sub') }
configure(subProjects) {
apply plugin: 'war'
}
獨(dú)享配置
到此為止,我們所有的Task定義工作都是在root-project中進(jìn)行的,而sub-project1和sub-project2中的build.gradle文件依然什么都沒(méi)有。事實(shí)上,我們可以將所有對(duì)子Project的配置均放在根Project中進(jìn)行。在上面的例子中,我們通過(guò)allprojects()和subprojects()將所有的子Project都包含在了配置之內(nèi),其實(shí)我們還可以對(duì)單個(gè)Project進(jìn)行單獨(dú)配置。比如,在root-project的build.gradle中加入:
project(':sub-project1') {
task forProject1 << {
println 'for project 1'
}
}
以上腳本向sub-project1中加入了名為forProject1的Task,在執(zhí)行“gradle forProject1”時(shí),終端輸出如下:
:sub-project1:forProject1
for project 1
注意這里子項(xiàng)目名字前面有一個(gè)冒號(hào)(:)。 通過(guò)這種方式,指定對(duì)應(yīng)的子項(xiàng)目,并對(duì)其進(jìn)行配置。
(2)我們還可以在每個(gè)子項(xiàng)目的目錄里建立自己的構(gòu)建腳本。在上例中,可以在子項(xiàng)目core目錄下為其建立一個(gè)build.gradle文件,并在該構(gòu)建腳本中配置core子項(xiàng)目所需的所有配置。例如,在該build.gradle文件中添加如下配置:
ext{
hibernateVersion = ‘4.2.1.Final’
}
dependencies {
compile “org.hibernate:hibernate-core:${hibernateVersion}”
}