Gradle7.0,依賴統(tǒng)一管理的全新方式,了解一下~

作者 | RicardoMJiang
我估計用到這么高版本的同學(xué)非常少,大家可以簡單了解下,做個收藏,未來用到可以過來查就行。
前言
隨著項目的不斷發(fā)展,項目中的依賴也越來越多,有時可能會有幾百個,這個時候?qū)椖恳蕾囎鲆粋€統(tǒng)一的管理很有必要,我們一般會有以下需求:
1、項目依賴統(tǒng)一管理,在單獨文件中配置。
2、不同Module中的依賴版本號統(tǒng)一。
3、不同項目中的依賴版本號統(tǒng)一。
針對這些需求,目前其實已經(jīng)有了一些方案:
使用循環(huán)優(yōu)化Gradle依賴管理
https://juejin.cn/post/6947675376835362846#heading-2
使用buildSrc管理Gradle依賴
https://juejin.cn/post/6844903615346245646
使用includeBuild統(tǒng)一配置依賴版本
https://juejin.cn/post/6844904169833234439
上面的方案支持在不同Module間統(tǒng)一版本號,同時如果需要在項目間共享,也可以做成Gradle插件發(fā)布到遠端,已經(jīng)基本可以滿足我們的需求。
不過Gradle7.0推出了一個新的特性,使用Catalog統(tǒng)一依賴版本,它支持以下特性:
1、對所有module可見,可統(tǒng)一管理所有module的依賴。
2、支持聲明依賴bundles,即總是一起使用的依賴可以組合在一起。
3、支持版本號與依賴名分離,可以在多個依賴間共享版本號。
4、支持在單獨的libs.versions.toml文件中配置依賴。
5、支持在項目間共享依賴。
如果您正在學(xué)習(xí)Spring Boot,推薦一個連載多年還在繼續(xù)更新的免費教程:http://blog.didispace.com/spring-boot-learning-2x/
1 使用Version Catalog
注意,Catalog仍然是一個孵化中的特性,如需使用,需要在settings.gradle中添加以下內(nèi)容:
enableFeaturePreview('VERSION_CATALOGS')
從命名上也可以看出,Version Catalog其實就是一個版本的目錄,我們可以從目錄中選出我們需要的依賴使用。
我們可以通過如下方式使用Catalog中聲明的依賴。
dependencies {
implementation(libs.retrofit)
implementation(libs.groovy.core)
}
在這種情況下,libs是一個目錄,retrofit表示該目錄中可用的依賴項。與直接在構(gòu)建腳本中聲明依賴項相比,Version Catalog具有許多優(yōu)點:
1、對于每個catalog,Gradle都會生成類型安全的訪問器,以便你在IDE中可以自動補全。(注:目前在build.gradle中還不能自動補全,可能是指kts或者開發(fā)中?)
2、聲明在catalog中的依賴對所有module可見,當(dāng)修改版本號時,可以統(tǒng)一管理統(tǒng)一修改。
3、catalog支持聲明一個依賴bundles,即一些總是一起使用的依賴的組合。
4、catalog支持版本號與依賴名分離,可以在多個依賴間共享版本號。
2 聲明Version Catalog
Version Catalog可以在settings.gradle(.kts)文件中聲明。
dependencyResolutionManagement {
versionCatalogs {
libs {
alias('retrofit').to('com.squareup.retrofit2:retrofit:2.9.0')
alias('groovy-core').to('org.codehaus.groovy:groovy:3.0.5')
alias('groovy-json').to('org.codehaus.groovy:groovy-json:3.0.5')
alias('groovy-nio').to('org.codehaus.groovy:groovy-nio:3.0.5')
alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {
strictly '[3.8, 4.0['
prefer '3.9'
}
}
}
}
別名必須由一系列以破折號(-,推薦)、下劃線 (_) 或點 (.) 分隔的標(biāo)識符組成。
標(biāo)識符本身必須由ascii字符組成,最好是小寫,最后是數(shù)字。
值得注意的是,groovy-core會被映射成libs.groovy.core。
如果你想避免映射可以使用大小寫來區(qū)分,比如groovyCore會被處理成libs.groovyCore。
3 具有相同版本號的依賴
在上面的示例中,我們可以看到三個groovy依賴具有相同的版本號,我們可以把它們統(tǒng)一起來。
dependencyResolutionManagement {
versionCatalogs {
libs {
version('groovy', '3.0.5')
version('compilesdk', '30')
version('targetsdk', '30')
alias('groovy-core').to('org.codehaus.groovy', 'groovy').versionRef('groovy')
alias('groovy-json').to('org.codehaus.groovy', 'groovy-json').versionRef('groovy')
alias('groovy-nio').to('org.codehaus.groovy', 'groovy-nio').versionRef('groovy')
alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {
strictly '[3.8, 4.0['
prefer '3.9'
}
}
}
}
除了在依賴中,我們同樣可以在build.gradle中獲取版本,比如可以用來指定compileSdk等。
android {
compileSdk libs.versions.compilesdk.get().toInteger()
defaultConfig {
applicationId "com.zj.gradlecatalog"
minSdk 21
targetSdk libs.versions.targetsdk.get().toInteger()
}
}
如上,可以使用catalog統(tǒng)一compileSdk,targetSdk,minSdk的版本號。
如果您正在學(xué)習(xí)Spring Boot,推薦一個連載多年還在繼續(xù)更新的免費教程:http://blog.didispace.com/spring-boot-learning-2x/
4 依賴bundles
因為在不同的項目中經(jīng)常系統(tǒng)地一起使用某些依賴項,所以Catalog提供了bundle(依賴包)的概念。依賴包基本上是幾個依賴項打包的別名。
例如,你可以這樣使用一個依賴包,而不是像上面那樣聲明 3 個單獨的依賴項:
dependencies {
implementation libs.bundles.groovy
}
groovy依賴包聲明如下:
dependencyResolutionManagement {
versionCatalogs {
libs {
version('groovy', '3.0.5')
version('checkstyle', '8.37')
alias('groovy-core').to('org.codehaus.groovy', 'groovy').versionRef('groovy')
alias('groovy-json').to('org.codehaus.groovy', 'groovy-json').versionRef('groovy')
alias('groovy-nio').to('org.codehaus.groovy', 'groovy-nio').versionRef('groovy')
alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {
strictly '[3.8, 4.0['
prefer '3.9'
}
bundle('groovy', ['groovy-core', 'groovy-json', 'groovy-nio'])
}
}
}
如上所示:添加groovy依賴包等同于添加依賴包下的所有依賴項。
5 插件版本
除了Library之外,Catalog還支持聲明插件版本。
因為library由它們的group、artifact和version表示,但Gradle插件僅由它們的id和version標(biāo)識。
因此,插件需要單獨聲明:
dependencyResolutionManagement {
versionCatalogs {
libs {
alias('jmh').toPluginId('me.champeau.jmh').version('0.6.5')
}
}
}
然后可以在plugins塊下面使用:
plugins {
id 'java-library'
id 'checkstyle'
// 使用聲明的插件
alias(libs.plugins.jmh)
}
6 在單獨文件中配置Catalog
除了在settings.gradle中聲明Catalog外,也可以通過一個單獨的文件來配置Catalog。
如果在根構(gòu)建的gradle目錄中找到了libs.versions.toml文件,則將使用該文件的內(nèi)容自動聲明一個Catalog。
TOML文件主要由4個部分組成:
[versions] 部分用于聲明可以被依賴項引用的版本。
[libraries] 部分用于聲明Library的別名。
[bundles] 部分用于聲明依賴包。
[plugins] 部分用于聲明插件。
如下所示:
[versions]
groovy = "3.0.5"
checkstyle = "8.37"
compilesdk = "30"
targetsdk = "30"
[libraries]
retrofit = "com.squareup.retrofit2:retrofit:2.9.0"
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } }
[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]
[plugins]
jmh = { id = "me.champeau.jmh", version = "0.6.5" }
如上所示,依賴可以定義成一個字符串,也可以將module與version分離開來。
其中versions可以定義成一個字符串,也可以定義成一個范圍,詳情可參見rich-version。
https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints
[versions]
my-lib = { strictly = "[1.0, 2.0[", prefer = "1.2" }
7 在項目間共享Catalog
Catalog不僅可以在項目內(nèi)統(tǒng)一管理依賴,同樣可以實現(xiàn)在項目間共享。
例如我們需要在團隊內(nèi)制定一個依賴規(guī)范,不同組的不同項目需要共享這些依賴,這是個很常見的需求。
通過文件共享
Catalog支持通過從Toml文件引入依賴,這就讓我們可以通過指定文件路徑來實現(xiàn)共享依賴。
如下所示,我們在settins.gradle中配置如下:
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../gradle/libs.versions.toml"))
}
}
}
此技術(shù)可用于聲明來自不同文件的多個目錄:
dependencyResolutionManagement {
versionCatalogs {
// 聲明一個'testLibs'目錄, 從'test-libs.versions.toml'文件中
testLibs {
from(files('gradle/test-libs.versions.toml'))
}
}
}
發(fā)布插件實現(xiàn)共享
雖然從本地文件導(dǎo)入Catalog很方便,但它并沒有解決在組織或外部消費者中共享Catalog的問題。
我們還可能通過Catalog插件來發(fā)布目錄,這樣用戶直接引入這個插件即可。
Gradle提供了一個Catalog插件,它提供了聲明然后發(fā)布Catalog的能力。
1. 首先引入兩個插件
plugins {
id 'version-catalog'
id 'maven-publish'
}
然后,此插件將公開可用于聲明目錄的catalog擴展。
2. 定義目錄
上面引入插件后,即可使用catalog擴展定義目錄。
catalog {
// 定義目錄
versionCatalog {
from files('../libs.versions.toml')
}
}
然后可以通過maven-publish插件來發(fā)布目錄。
3. 發(fā)布目錄
publishing {
publications {
maven(MavenPublication) {
groupId = 'com.zj.catalog'
artifactId = 'catalog'
version = '1.0.0'
from components.versionCatalog
}
}
}
我們定義好groupId,artifactId,version,from就可以發(fā)布了。
我們這里發(fā)布到mavenLocal,你也可以根據(jù)需要配置發(fā)布到自己的maven。
4. 使用目錄
因為我們已經(jīng)發(fā)布到了mavenLocal,在倉庫中引入mavenLocal就可以使用插件了。
# settings.gradle
dependencyResolutionManagement {
//...
repositories {
mavenLocal()
//...
}
}
enableFeaturePreview('VERSION_CATALOGS')
dependencyResolutionManagement {
versionCatalogs {
libs {
from("com.zj.catalog:catalog:1.0.0")
// 我們也可以重寫覆蓋catalog中的groovy版本
version("groovy", "3.0.6")
}
}
}
如上就成功引入了插件,就可以使用catalog中的依賴了。
總結(jié)
項目間共享依賴是比較常見的需求,雖然我們也可以通過自定義插件實現(xiàn),但還是不夠方便 Gradle官方終于推出了Catalog,讓我們可以方便地實現(xiàn)依賴的共享,Catalog主要具有以下特性:
1、對所有module可見,可統(tǒng)一管理所有module的依賴。
2、支持聲明依賴bundles,即總是一起使用的依賴可以組合在一起。
3、支持版本號與依賴名分離,可以在多個依賴間共享版本號。
4、支持在單獨的libs.versions.toml文件中配置依賴。
5、支持在項目間共享依賴。
參考資料
Sharing dependency versions between projects
https://docs.gradle.org/current/userguide/platforms.html
往期推薦
技術(shù)交流群
最近有很多人問,有沒有讀者交流群,想知道怎么加入。加入方式很簡單,有興趣的同學(xué),只需要點擊下方卡片,回復(fù)“加群“,即可免費加入我們的高質(zhì)量技術(shù)交流群!
點擊閱讀原文,直達教程目錄
