Gradle目前的版本是2.4,根據(jù)其Wiki上的Roadmap,Gradle有著讓很多成熟項(xiàng)目都汗顏的文檔,其包括了安裝指南、基本教程、以及一份近300頁(yè)的全面用戶(hù)指南。這對(duì)于用戶(hù)來(lái)說(shuō)是非常友好的,同時(shí)也說(shuō)明了Gradle的開(kāi)發(fā)者對(duì)這個(gè)項(xiàng)目非常有信心,要知道編寫(xiě)并維護(hù)文檔可不是件輕松的工作,對(duì)于Gradle這樣未來(lái)仍可能發(fā)生很大變動(dòng)的項(xiàng)目來(lái)說(shuō)尤為如此。
類(lèi)似于Maven的pom.xml文件,每個(gè)Gradle項(xiàng)目都需要有一個(gè)對(duì)應(yīng)的build.gradle文件,該文件定義一些任務(wù)(task)來(lái)完成構(gòu)建工作,當(dāng)然,每個(gè)任務(wù)是可配置的,任務(wù)之間也可以依賴(lài),用戶(hù)亦能配置缺省任務(wù),就像這樣:
defaultTasks 'taskB'
task taskA << {
println "i'm task A"
}
task taskB << {
println "i'm task B, and I depend on " + taskA.name
}
taskB.dependsOn taskA
運(yùn)行命令$ gradle -q之后(參數(shù)q讓Gradle不要打印錯(cuò)誤之外的日志),就能看到如下的預(yù)期輸出:
i'm task A
i'm task B, and I depend on taskA
這不是和Ant如出一轍么?的確是這樣,這種“任務(wù)”的概念與用法與Ant及其相似。Ant任務(wù)是Gradle世界的第一公民,Gradle對(duì)Ant做了很好的集成。除此之外,由于Gradle使用的Grovvy腳本較XML更為靈活,因此,即使我自己不是Ant用戶(hù),我也仍然覺(jué)得Ant用戶(hù)會(huì)喜歡上Gradle。
我們知道依賴(lài)管理、倉(cāng)庫(kù)、約定優(yōu)于配置等概念是Maven的核心內(nèi)容,拋開(kāi)其實(shí)現(xiàn)是否最優(yōu)不談,概念本身沒(méi)什么問(wèn)題,并且已經(jīng)被廣泛學(xué)習(xí)和接受。那Gradle實(shí)現(xiàn)了這些優(yōu)秀概念了么?答案是肯定的。
先看依賴(lài)管理,我有一個(gè)簡(jiǎn)單的項(xiàng)目依賴(lài)于一些第三方類(lèi)庫(kù)包括SpringFramework、JUnit、Kaptcha等等。原來(lái)的Maven POM配置大概是這樣的(篇幅關(guān)系,省略了部分父POM配置):
<properties>
<kaptcha.version>2.3</kaptcha.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
然后我將其轉(zhuǎn)換成Gradle腳本,結(jié)果是驚人的:
dependencies {
compile('org.springframework:spring-core:2.5.6')
compile('org.springframework:spring-beans:2.5.6')
compile('org.springframework:spring-context:2.5.6')
compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')
testCompile('junit:junit:4.7')
}
注意配置從原來(lái)的28行縮減至7行!這還不算我省略的一些父POM配置。依賴(lài)的groupId、artifactId、 version,scope甚至是classfier,一點(diǎn)都不少。較之于Maven或者Ant的XML配置腳本,Gradle使用的Grovvy腳本殺傷力太大了,愛(ài)美之心,人皆有之,相比于七旬老婦松松垮垮的皺紋,大家肯定都喜歡少女緊致的臉蛋,XML就是那老婦的皺紋。
關(guān)于Gradle的依賴(lài)管理起初我有一點(diǎn)擔(dān)心,就是它是否有傳遞性依賴(lài)的機(jī)制呢?經(jīng)過(guò)文檔閱讀和實(shí)際試驗(yàn)后,這個(gè)疑慮打消了,Gradle能夠解析現(xiàn)有的Maven POM或者Ivy的XML配置,從而得到傳遞性依賴(lài)的信息,并且引入到當(dāng)前項(xiàng)目中,這實(shí)在是一個(gè)聰明的做法。在此基礎(chǔ)上,它也支持排除傳遞性依賴(lài)或者干脆關(guān)閉傳遞性依賴(lài),其中第二點(diǎn)是Maven所不具備的特性。
自動(dòng)化依賴(lài)管理的基石是倉(cāng)庫(kù),Maven中央倉(cāng)庫(kù)已經(jīng)成為了Java開(kāi)發(fā)者不可或缺的資源,Gradle既然有依賴(lài)管理,那必然也得用到倉(cāng)庫(kù),這當(dāng)然也包括了Maven中央倉(cāng)庫(kù),就像這樣:
```
repositories {
mavenLocal()
mavenCentral()
mavenRepo urls: "http://repository.sonatype.org/content/groups/forge/"
}
```
這段代碼幾乎不用解釋?zhuān)褪窃贕radle中配置使用Maven本地倉(cāng)庫(kù)、中央倉(cāng)庫(kù)、以及自定義地址倉(cāng)庫(kù)。在我實(shí)際構(gòu)建項(xiàng)目的時(shí)候,能看到終端打印的下載信息,下載后的文件被存儲(chǔ)在 USER_HOME/.gradle/cache/ 目錄下供項(xiàng)目使用,這種實(shí)現(xiàn)的方法與Maven又是及其類(lèi)似了,可以說(shuō)Gradle不僅最大限度的繼承Maven的很多理念,倉(cāng)庫(kù)資源也是直接拿來(lái)用。
Gradle項(xiàng)目使用Maven項(xiàng)目生成的資源已經(jīng)不是個(gè)問(wèn)題了,接著需要反過(guò)來(lái)考慮,Maven用戶(hù)是否能夠使用 Gradle生成的資源呢?或者更簡(jiǎn)單點(diǎn)問(wèn),Gradle項(xiàng)目生成的構(gòu)件是否可以發(fā)布到Maven倉(cāng)庫(kù)中供人使用呢?這一點(diǎn)非常重要,因?yàn)槿绻霾坏竭@一點(diǎn),你可能就會(huì)丟失大量的用戶(hù)。幸運(yùn)的是Gradle再次給出了令人滿(mǎn)意的答案。使用Gradle的Maven Plugin,用戶(hù)就可以輕松地將項(xiàng)目構(gòu)件上傳到Maven倉(cāng)庫(kù)中:
```
apply plugin: 'maven'
...
uploadArchives {
repositories.mavenDeployer {
repository(url: "http://localhost:8088/nexus/content/repositories/snapshots/") {
authentication(userName: "admin", password: "admin123")
pom.groupId = "com.juvenxu"
pom.artifactId = "account-captcha"
}
}
}
```
在上傳的過(guò)程中,Gradle能夠基于build.gradle生成對(duì)應(yīng)的Maven POM文件,用戶(hù)可以自行配置POM信息,比如這里的groupId和artifactId,而諸如依賴(lài)配置這樣的內(nèi)容,Gradle是會(huì)自動(dòng)幫你進(jìn)行轉(zhuǎn)換的。由于Maven項(xiàng)目之間依賴(lài)交互的直接途徑就是倉(cāng)庫(kù),而Gradle既能夠使用Maven倉(cāng)庫(kù),也能以Maven的格式將自己的內(nèi)容發(fā)布到倉(cāng)庫(kù)中,因此從技術(shù)角度來(lái)說(shuō),即使在一個(gè)基于Maven的大環(huán)境中,局部使用Gradle也幾乎不會(huì)是一個(gè)問(wèn)題。
## 約定優(yōu)于配置