Gradle 在它的核心中有意地提供了一些小但有用的功能,用于在真實世界中的自動化。所有有用的功能,例如以能夠編譯 Java 代碼為例,都是通過插件進行添加的。插件添加了新任務 (例如JavaCompile),域對象 (例如SourceSet),約定(例如主要的 Java 源代碼是位于 src/main/java),以及擴展的核心對象和其他插件的對象。
在這一章中,我們將討論如何使用插件以及術語和插件相關的概念。
插件都認為是被應用,通過 Project.apply() 方法來完成。
應用插件
build.gradle
apply plugin: 'java'
插件都有表示它們自己的一個短名稱。. 在上述例子中,我們使用短名稱 java 去應用 JavaPlugin。
我們還可以使用下面的語法:
通過類型應用插件
build.gradle
apply plugin: org.gradle.api.plugins.JavaPlugin
由于 Gradle 的默認導入,您還可以這樣寫:
通過類型應用插件
build.gradle
apply plugin: JavaPlugin
插件的應用是冪等的。也就是說,一個插件可以被應用多次。如果以前已應用了該插件,任何進一步的應用都不會再有任何效果。
一個插件是任何實現(xiàn)了 Plugin 接口的簡單的類。Gradle 提供了核心插件作為其發(fā)行包的一部分,所以簡單地應用如上插件是你所需要做的。然而,對于第三方插件,你需要進行配置以使插件在構建類路徑中可用。有關如何進行此操作的詳細信息。
把插件應用到項目中可以讓插件來擴展項目的功能。它可以做的事情如:
讓我們來看看:
通過插件添加任務
build.gradle
apply plugin: 'java'
task show << {
println relativePath(compileJava.destinationDir)
println relativePath(processResources.destinationDir)
}
gradle -q show 的輸出結果
> gradle -q show
build/classes/main
build/resources/main
Java 插件已經(jīng)向項目添加了 compileJava 任務和 processResources 任務,并且配置了這兩個任務的 destinationDir 屬性。
插件可以通過智能的方法對項目進行預配置以支持約定優(yōu)于配置。Gradle 對此提供了機制和完善的支持,而它是強大-然而-簡潔的構建腳本中的一個關鍵因素。
在上面的示例中我們看到,Java 插件添加了一個任務,名字為 compileJava ,有一個名為 destinationDir 的屬性(即配置編譯的 Java 代碼存放的地方)。Java 插件默認此屬性指向項目目錄中的 build/classes/main。這是通過一個合理的默認的約定優(yōu)于配置的例子。
我們可以簡單地通過給它一個新的值來更改此屬性。
更改插件的默認設置
build.gradle
apply plugin: 'java'
compileJava.destinationDir = file("$buildDir/output/classes")
task show << {
println relativePath(compileJava.destinationDir)
}
gradle -q show 的輸出結果
> gradle -q show
build/output/classes
然而,compileJava 任務很可能不是唯 一需要知道類文件在哪里的任務。
Java 插件添加了 source sets 的概念 (見SourceSet) 來描述的源文件集的各個方面,其中一個方面是在編譯的時候這些類文件應該被寫到哪個地方。Java 插件將 compileJava 任務的 destinationDir 屬性映射到源文件集的這一個方面。
我們可以通過這個源碼集修改寫入類文件的位置。
插件中的約定對象
build.gradle
apply plugin: 'java'
sourceSets.main.output.classesDir = file("$buildDir/output/classes")
task show << {
println relativePath(compileJava.destinationDir)
}
gradle -q show 的輸出結果
> gradle -q show
build/output/classes
在上面的示例中,我們應用 Java 插件,除其他外,還做了下列操作:
所有這一切都發(fā)生在 apply plugin: "java" 這一步過程中。在上面例子中,我們在約定配置被執(zhí)行之后,修改了類文件所需的位置。在上面的示例中可以注意到,compileJava.destinationDir 的值也被修改了,以反映出配置的修改。
考慮一下另一種消費類文件的任務的情況。如果這個任務使用 sourceSets.main.output.classesDir 的值來配置,那么修改了這個位置的值,無論它是什么時候被修改,將同時更新 compileJava 任務和這一個消費者任務。
這種配置對象的屬性以在所有時間內(nèi)(甚至當它更改的時候)反映另一個對象的任務的值的能力被稱為“映射約定”。它可以令 Gradle 通過約定優(yōu)于配置及合理的默認值來實現(xiàn)簡潔的配置方式。而且,如果默認約定需要進行修改時,也不需要進行完全的重新配置。如果沒有這一點,在上面的例子中,我們將不得不重新配置需要使用類文件的每個對象。
更多建議: