關(guān)于我在寫(xiě)Gradle時(shí)我究竟在搞什么
疫情原因,五一有些不爽,放假歸來(lái),怒更一貼。
上班第一天,被公司架構(gòu)大佬分派了一個(gè)Event Mesh中間件的維護(hù)工作,本著面向薪資編程的初衷,打開(kāi)了項(xiàng)目打算研究一下,發(fā)現(xiàn)了一個(gè)不得了的事情:

可以看到每個(gè)項(xiàng)目中找不到對(duì)于javaer來(lái)說(shuō)熟悉的pom.xml,取而代之的是每個(gè)項(xiàng)目模塊里都有一個(gè)build.gradle、gradle.properties,另外在項(xiàng)目根目錄下還有一個(gè)setting.gradle.
很明顯,項(xiàng)目沒(méi)有采用maven而是用的Gradle來(lái)做版本依賴控制,沒(méi)有按著公司規(guī)范進(jìn)行,然后雷記想到:把這個(gè)事兒說(shuō)出來(lái),能換條命嘛好漢
提起Gradle,一把辛酸淚。為何出此言呢?且看分解:
????·build.gradle:文件必須。定義了一個(gè)模塊和編譯用的tasks,它一般是放在項(xiàng)目的模塊中,也可以放在項(xiàng)目的根目錄用來(lái)作為編譯結(jié)構(gòu)全局設(shè)置。
????·gradle.properties:文件必須。描述了哪一個(gè)模塊需要參與構(gòu)建。每一個(gè)多模塊的構(gòu)建都必須在項(xiàng)目結(jié)構(gòu)的根目錄中加入這個(gè)設(shè)置文件。
????·setting.gradle:配置構(gòu)建屬性,不是必須的。
DEMO 4?build.gradle
task hello {//定義一個(gè)hello的task
????doLast{//實(shí)現(xiàn)doLast方法
????????println 'Hello world!'
????}
}
終端>gradle hello執(zhí)行即可打印,實(shí)際使用時(shí)task之間是相互依賴的。所以存在一個(gè)task依賴另一個(gè)task,此時(shí)在task定義時(shí)加入dependsOn:
task hello << {
????println ‘Hello world!’
}
task intro(dependsOn:hello) << {
? ? println ‘i'm gradle’
}
Gradle插件
Gradle的設(shè)計(jì)理念是,所有有用的特性都由Gradle插件提供,例如編寫(xiě)一個(gè)Java項(xiàng)目時(shí),需要使用到 Java 插件, 它會(huì)將許多任務(wù)自動(dòng)的加入到你項(xiàng)目里。Gradle本身提供了一系列的標(biāo)準(zhǔn)插件,無(wú)需多余配置只需要在你的build.gradle文件中加入 apply plugin: 'java',便可以引入許多task,只需要使用對(duì)應(yīng)的task即可進(jìn)行項(xiàng)目構(gòu)建:
????·gradle build:編譯整個(gè)項(xiàng)目,執(zhí)行代碼編譯、代碼檢查和單元測(cè)試;
????·gradle assemble:編譯并打包代碼,不運(yùn)行代碼檢查和單元檢測(cè);
????·gradle clean:刪除build生成的目錄和所有生成的文件;
????·gradle check:編譯并測(cè)試代碼;
Gradle各個(gè)task關(guān)系圖,可以發(fā)現(xiàn)build實(shí)際為將一批task批量執(zhí)行:

外部依賴
做java開(kāi)發(fā)時(shí),我們有時(shí)會(huì)依賴第三方外部庫(kù),在gradle同樣需要明確去哪里尋找,在 Gradle 中, JAR 文件位于一個(gè)倉(cāng)庫(kù)中,這里的倉(cāng)庫(kù)類似于maven 的倉(cāng)庫(kù),首先指定maven的倉(cāng)庫(kù)地址:
repositories?{
????mavenCentral()????
}
mavenCentral()是Gradle內(nèi)置的一個(gè)maven倉(cāng)庫(kù)地址,加入maven倉(cāng)庫(kù)后,就可以直接加入maven倉(cāng)庫(kù)中的外部依賴,如果這個(gè)外部依賴不存在,gradle會(huì)聯(lián)網(wǎng)去maven倉(cāng)庫(kù)中自動(dòng)下載它,并將它緩存到本地,下次再使用時(shí)會(huì)優(yōu)先從本地緩存中查找該依賴,引用一個(gè)外部依賴需要指定使用的group, name 和 version 屬性,三者缺一不可。:??
dependencies?{
????compile?group:?'commons-collections',?name:?'commons-collections',?version:?'3.2'
????//?簡(jiǎn)化寫(xiě)法
????//?compile?'commons-collections:commons-collections:3.2'
}
本地依賴:
Gradle也可以從本地目錄中引入JAR包依賴,可以單一引入指定的某一JAR包,也可以引入某目錄下所有的JAR包:
dependencies?{
????compile?files('dir/file.jar')
????compile?fileTree(dir:?'libs',?include:?'*.jar')
}
項(xiàng)目依賴:
一個(gè)完整的項(xiàng)目由多個(gè)子項(xiàng)目構(gòu)成。在Gradle中,使用文件settings.gradle定義當(dāng)前項(xiàng)目的子項(xiàng)目。默認(rèn)情況下,每個(gè)子項(xiàng)目的名稱對(duì)應(yīng)著當(dāng)前操作系統(tǒng)目錄下的一個(gè)子目錄:
include 'sub-project1', 'sub-project2', 'sub-project3'
如sub-project1依賴sub-project2,則在sub-project1的build.gradle中加入以下配置即可:
dependencies?{
????compile?project(':sub-project2')
}
依賴關(guān)系管理
gradle需要明確被構(gòu)建或運(yùn)行的項(xiàng)目,找到后將這些導(dǎo)入的文件視為項(xiàng)目的依賴;
gradle需要構(gòu)建或打包項(xiàng)目,將這些導(dǎo)出的文件視為項(xiàng)目的發(fā)布;
例如在編譯源碼時(shí)項(xiàng)目需要Hibernate的某些jar包被加入到工程中,而在進(jìn)行單元測(cè)試時(shí)還另需要Junit的某些jar被加入。這些被引入的jar包就是項(xiàng)目的依賴。Gradle允許對(duì)依賴進(jìn)行相應(yīng)的配置,通過(guò)不同的配置可以形成不同的依賴效果,例如:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
在項(xiàng)目編譯時(shí)期,junit的jar包不會(huì)被引入,只有在單元測(cè)試時(shí)才會(huì)被引入。這樣,就可以在不同的場(chǎng)景下加入相應(yīng)的依賴關(guān)系,非常的靈活。Java 插件中定義了許多標(biāo)準(zhǔn)的配置:
compile 用來(lái)編譯項(xiàng)目源代碼的依賴
runtime 在運(yùn)行時(shí)被生成的類使用的依賴。 默認(rèn)的, 也包含了compile時(shí)的依賴。
testCompile 編譯測(cè)試代碼的依賴。 默認(rèn)的, 包含runtime時(shí)的依賴和compile時(shí)的依賴。
testRuntime 運(yùn)行測(cè)試所需要的依賴。 默認(rèn)的, 包含上面三個(gè)依賴。
函數(shù)式編程_類型拆裝及重載解析函數(shù)式編程關(guān)于二進(jìn)制接口兼容性