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