Gradle:Project,Tasks and Plugins
讓我們回憶上一節(jié),在此基礎(chǔ)上增加點東西。
總的來說,build.gradle文件是用來驅(qū)動Gradle構(gòu)建過程的,它包含了指令指導(dǎo)如何構(gòu)建。如果沒有這些構(gòu)建工具我們也會做這些任務(wù),比如編譯,測試,構(gòu)建jar,部署等。
我們不必像上一節(jié)那樣手寫任務(wù),我們的IDES,插件會幫我們解決。有許多插件會幫我們自動調(diào)用任務(wù),如果我們遵守一定的語法,剩下的就由gradle幫我們解決。
插件(Plugin)是什么?插件是一種拓展Gradle的機制。Gradle需要知道如何去構(gòu)建任務(wù)。當我們已知構(gòu)建的過程,可以以此創(chuàng)建預(yù)構(gòu)建的任務(wù)。這就是插件的角色。
我們不去關(guān)注如何寫插件,我們學習使用已有的插件幫助我們完成任務(wù)。這些插件增加了一些任務(wù)供我們直接使用。
Java plugin
我們從對java開發(fā)者最重要的java插件開始。不出所料,該插件增加了如下的能力。
1.編譯
2.測試
3.打包
這些包含了我們能對java工程所做的一切。打包一般情況下指jar文件。
任何我們需要使用的插件都需要在build.gradle文件中添加如下語句
apply plugin: <plugin-name>
我們這里,由于我們要使用java插件,我們將使用如下的語句:
apply plugin: "java"
讓我們從理解這背后發(fā)生了什么開始。
創(chuàng)建文件夾example2。你能使用任意文件夾。只要保證gradle在任何文件夾都可以訪問。
在我們的文件夾中創(chuàng)建build.gradle文件,添加下面這行:
apply plugin: "java"
正如前面提到的,插件會增加大量的任務(wù)來處理Java工程。讓我們執(zhí)行如下命令來理解都增加了哪些任務(wù):
gradle tasks
將會有如下輸出:
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend
on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles classes 'main'.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles classes 'test'.
如你看到的,已經(jīng)增加了許多任務(wù),大部分也很好理解:
1.clean會刪除構(gòu)建目錄,所有的classes將會被移除以便重新編譯。
2.assemble將會創(chuàng)建jar文件。
這些任務(wù)會相互依賴,具體看參考文檔dependency grgh。
Basic Java Project with Gradle Java plugin
有了這些信息,那么問題來了,我們?nèi)绾握{(diào)用這些任務(wù)呢?
我們已經(jīng)知道如何調(diào)用任務(wù),我們需要如下命令gradle <task-name>。具體到我們的java工程該如何做呢?
我們將遵循一定的規(guī)則,這就意味著java插件將會到指定的文件夾中尋找文件。你可以自定義規(guī)則,但這不在我們討論的范圍之內(nèi)。
從官方文檔中,java插件遵循如下的文件結(jié)構(gòu):

這不是強制的,如果你想有不同的文件結(jié)構(gòu),查看官方文檔的source sets。
什么是source sets?它組織了需要編譯和構(gòu)建的源文件。Java插件定義了2個標準的source set,main和test。main集合包含了源文件,這些文件將被編譯成jar文件。test集合包含單元測試代碼,使用JUnit或TestNG來執(zhí)行。
我們將按照默認的文件結(jié)構(gòu)來訪者我的源文件和測試文件,這意味著:
1.java文件放在src/main/java文件夾下
2.測試文件放在src/main/test文件夾下
我創(chuàng)建了包名com.mindstorm.quoteapp在src/main/java文件夾中,文件結(jié)構(gòu)如下:

在quoteapp文件夾中有一個名叫Quote.java文件:
package com.mindstorm.quoteapp;
public class Quote {
private Long id;
private String who;
private String what;
public void setId(Long id) {
this.id = id;
}
public void setWho(String who) {
this.who = who;
}
public void setWhat(String what) {
this.what = what;
}
public Long getId() {
return id;
}
public String getWho() {
return who;
}
public String getWhat() {
return what;
}
}
在我們的根目錄下example2中有build.gradle文件,該文件只有一條語句apply plugin: “java”
現(xiàn)在,執(zhí)行如下命令:
gradle assemble
這條命令將你的java文件編譯,構(gòu)建成jar文件。多個其他任務(wù)會被執(zhí)行,
輸出如下:
E:\gradle-projects\example2>gradle assemble
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
這條命令的結(jié)果是什么呢?如果一切正常,將會有build文件在你的根目錄。在該文件夾下的libs文件夾中有example2.jar。
如果你希望清理構(gòu)建目錄,調(diào)用gradle clean命令,然后gradle assemble命令。
下面這條命令將會執(zhí)行check,assemble任務(wù):
gradle -q build
我們稍加改進。如果我們希望生成的jar文件有不同的名字,更新build.gradle文件:
apply plugin: 'java'
archivesBaseName = "quote"
version = '1.0-FINAL'
現(xiàn)在執(zhí)行gradle assemble,Jar文件將按如下規(guī)則命名<name>-<version>.jar,這里是quote-1.0-FINAL.jar。
更多細節(jié)參考官方文檔: official page of the Java plugin.
The beginning of Dependencies
你的Java工程很少不依賴第三方庫,考慮上面的Quote.java文件,如果我們增加toString()方法,使用到了第三方庫:Apache Commons JAR.
我們看下代碼:
package com.mindstorm.quoteapp;
import org.apache.commons.lang3.builder.ToStringBuilder;
public class Quote {
private Long id;
private String who;
private String what;
public void setId(Long id) {
this.id = id;
}
public void setWho(String who) {
this.who = who;
}
public void setWhat(String what) {
this.what = what;
}
public Long getId() {
return id;
}
public String getWho() {
return who;
}
public String getWhat() {
return what;
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
如果你執(zhí)行g(shù)radle assemble命令,將會遇到問題。你將會看到編譯錯誤。
解決方法是修改build.gradle文件,以便它知道如下兩件事:
1.編譯過程中需要使用到什么Jar文件。
2.到哪里去找這些jar文件。
Gradle的Repository是保存jar文件的地方。Gradle支持主流的Repository比如Maven, lvy等。如果你了解Maven,這聽起來很熟悉。
為了配置遠程庫,在build.gradle中添加如下語句:
repositories {
mavenCentral()
}
這會使Gradle在指定的Maven中心庫需找依賴(JAR 文件)。
每個發(fā)布在Maven或其他中心庫的文件都有如下的特征:
1.group id
2.artifact id
3.version id
比如,你想定位Apache Commons3,3.2JAR,它將會以如下方式呈現(xiàn):
上面的圖片來自Maven中心庫,如果你對你的依賴有疑問,在Maven中心庫搜索。
Configurations provided by Java plugin
到現(xiàn)在我們?yōu)橹梗覀冎懒宋覀冃枰赽uild.gradle文件中提供額外的信息,通過這些信息可以定位到編譯時需要的Jar文件。我們明確了去哪里尋找,但是還沒有具體指定哪個文件,在我們這里是Apache Commons Lang library。
Gradle引入了Configurations,Configuration是一個依賴的集合,你能利用它們?yōu)槟愕墓こ搪暶黝~外的依賴。
Configuration有哪些?它們叫什么?插件會添加一系列Configurations,我們可以使用它們指定我們的依賴。對于Java 插件有如下標準配置,其中一部分如下:
1.compile
2.runtime
2.testCompile
3.testRuntime
這里我將會引用官方文檔:
compile
編譯源文件是需要的依賴。
runtime
運行時需要的依賴
testCompile
編譯測試源文件是需要的依賴
testRuntime
運行測試時需要的依賴
現(xiàn)在,我們在編譯Quote類時,需要依賴Apache Commons Lang 3.3.2,我們在build.gradle中添加如下條目:
apply plugin: 'java'
archivesBaseName = "quote"
version = '1.0-FINAL'
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
}
有些注意的地方:
1.每個依賴獨自定義
2.你首先指定配置名compile,然后指定庫的group, name, version。
3.當前只有一條編譯時依賴,你能添加更多其他依賴。
4.還有一個簡便的聲明依賴的方法:使用'group-value:name-value:version-value',上面的例子里也可以這樣聲明:
dependencies {
compile 'org.apache.commons:commons-lang3:3.3.2'
}
保存build.gradle,嘗試運行g(shù)radle assemble命令。這一次會自動從Maven中心庫下載jar文件,添加到本地緩存完成編譯過程。
注意
首次編譯時,需要連接網(wǎng)絡(luò),到Maven中心庫下載指定文件。以后將直接在緩存中獲取,所以確保網(wǎng)絡(luò)連接正常。
Some more dependencies
既然我們知道怎么添加編譯時依賴,自然需要弄明白怎么添加測試依賴。現(xiàn)在我們使用JUnit,測試實例保存在src/test/java文件夾中。
更新build.gradle文件:
apply plugin: 'java'
archivesBaseName = "quote"
version = '1.0-FINAL'
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
上面的格式非常熟悉,只是在版本號的地方,使用+號做了代替。這暗示Gradle獲取最新的依賴文件。
Download
你可以在這里(需要科學上網(wǎng))下載整個工程。