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