您可以指定具有精確版本或版本範圍的相依性,以定義您的專案可以使用的版本
dependencies {
implementation("org.springframework:spring-core:5.3.8")
implementation("org.springframework:spring-core:5.3.+")
implementation("org.springframework:spring-core:latest.release")
implementation("org.springframework:spring-core:[5.2.0, 5.3.8]")
implementation("org.springframework:spring-core:[5.2.0,)")
}
了解版本宣告
Gradle 支援多種宣告版本與範圍的方式
版本 | 範例 | 注意 |
---|---|---|
精確版本 |
|
特定版本。 |
Maven 樣式範圍 |
|
當缺少上限或下限時,範圍沒有上限或下限。 上限排除作用如同前綴排除。 |
前綴版本範圍 |
|
僅包含完全符合 宣告版本為 |
|
|
符合具有指定狀態的最高版本。請參閱 ComponentMetadata.getStatus()。 |
Maven |
|
表示快照版本。 |
Maven 樣式範圍
在 Maven 樣式中,有多種選項可以指示邊界
-
[
和]
表示包含邊界 →[1.1, 2.0]
-
(
和)
表示排除邊界 →(1.1, 2.0)
或(1.2, 1.5]
或[1.1, 2.0)
-
]
可以用來代替(
表示排除下限 →]1.2, 1.5]
而非(1.2, 1.5]
-
[
可以用來代替)
表示排除上限 →[1.1, 2.0[
而非[1.1, 2.0)
了解版本排序
dependencies {
implementation("org.springframework:spring-core:1.1") // This is a newer version than 1.a
implementation("org.springframework:spring-core:1.a") // This is a older version than 1.1
}
版本排序用於
-
判斷特定版本是否包含在範圍內。
-
判斷執行衝突解決時哪個版本最新(使用 「基礎版本」)。
版本根據以下規則排序
-
將版本拆分為部分
-
版本使用字元
[. - _ +]
分割為部分。 -
包含數字和字母的部分會進一步分割,例如,
1a1
變成1.a.1
。 -
僅比較部分,不比較分隔符號,因此
1.a.1
、1-a+1
、1.a-1
和1a1
是等效的。(注意:在衝突解決期間有 例外情況)。
-
-
比較等效部分
-
數值與數值:較高的數值被認為較高:
1.1 < 1.2
。 -
數值與非數值:數值部分高於非數值部分:
1.a < 1.1
。 -
非數值與非數值:部分按字母順序和區分大小寫比較:
1.A < 1.B < 1.a < 1.b
。 -
額外數值部分:具有額外數值部分的版本較高,即使它是零:
1.1 < 1.1.0
。 -
額外非數值部分:具有額外非數值部分的版本較低:
1.1.a < 1.1
。
-
-
特殊非數值部分
-
dev
低於任何其他非數值部分:1.0-dev < 1.0-ALPHA < 1.0-alpha < 1.0-rc
。 -
rc
、snapshot
、final
、ga
、release
和sp
高於任何其他字串部分,依此順序:1.0-zeta < 1.0-rc < 1.0-snapshot < 1.0-final < 1.0-ga < 1.0-release < 1.0-sp
。 -
這些特殊值不區分大小寫,且其排序不取決於使用的分隔符號:
1.0-RC-1 == 1.0.rc.1
。
-
宣告豐富版本
當您使用簡寫符號宣告版本時,該版本會被視為 必要版本
dependencies {
implementation("org.slf4j:slf4j-api:1.7.15")
}
dependencies {
implementation('org.slf4j:slf4j-api:1.7.15')
}
這表示最低版本將為 1.7.15
,並且可以由引擎樂觀地升級。
為了強制執行 嚴格版本 並確保僅使用相依性的指定版本,即使其他版本通常相容,也拒絕任何其他版本
dependencies {
implementation("org.slf4j:slf4j-api") {
version {
strictly("[1.7, 1.8[")
prefer("1.7.25")
}
}
}
dependencies {
implementation('org.slf4j:slf4j-api') {
version {
strictly '[1.7, 1.8['
prefer '1.7.25'
}
}
}
Gradle 支援豐富版本宣告模型,讓您可以結合不同層級的版本精確度。
關鍵術語,從最強到最弱依序為
strictly
或!!
-
這是最強的版本宣告。任何不符合此符號的版本都將被排除。如果用於宣告的相依性,
strictly
可以降級版本。對於傳遞相依性,如果找不到可接受的版本,相依性解析將會失敗。支援動態版本。
定義後,它會覆蓋任何先前的
require
宣告,並清除已在該相依性上宣告的任何先前reject
。
require
-
這確保選定的版本不能低於
require
接受的版本,但可以通過衝突解決更高,即使較高版本具有排除上限。這是直接相依性的預設行為。支援動態版本。
定義後,它會覆蓋任何先前的
strictly
宣告,並清除已在該相依性上宣告的任何先前reject
。
prefer
-
這是最弱的版本宣告。僅在未指定更強的非動態版本時適用。
此術語不支援動態版本,並且可以補充
strictly
或require
。定義後,它會覆蓋任何先前的
prefer
宣告,並清除已在該相依性上宣告的任何先前reject
。
此外,還有一個層次結構之外的術語
reject
-
此術語指定模組不接受的版本,如果選定拒絕的版本,將導致相依性解析失敗。
支援動態版本。
豐富版本宣告通過相依性或約束宣告上的 version
DSL 方法存取,這讓您可以存取 MutableVersionConstraint
dependencies {
implementation("org.slf4j:slf4j-api") {
version {
strictly("[1.7, 1.8[")
prefer("1.7.25")
}
}
constraints {
add("implementation", "org.springframework:spring-core") {
version {
require("4.2.9.RELEASE")
reject("4.3.16.RELEASE")
}
}
}
}
dependencies {
implementation('org.slf4j:slf4j-api') {
version {
strictly '[1.7, 1.8['
prefer '1.7.25'
}
}
constraints {
implementation('org.springframework:spring-core') {
version {
require '4.2.9.RELEASE'
reject '4.3.16.RELEASE'
}
}
}
}
為了強制執行 嚴格版本,您也可以使用 !!
符號
dependencies {
// short-hand notation with !!
implementation("org.slf4j:slf4j-api:1.7.15!!")
// is equivalent to
implementation("org.slf4j:slf4j-api") {
version {
strictly("1.7.15")
}
}
// or...
implementation("org.slf4j:slf4j-api:[1.7, 1.8[!!1.7.25")
// is equivalent to
implementation("org.slf4j:slf4j-api") {
version {
strictly("[1.7, 1.8[")
prefer("1.7.25")
}
}
}
dependencies {
// short-hand notation with !!
implementation('org.slf4j:slf4j-api:1.7.15!!')
// is equivalent to
implementation("org.slf4j:slf4j-api") {
version {
strictly '1.7.15'
}
}
// or...
implementation('org.slf4j:slf4j-api:[1.7, 1.8[!!1.7.25')
// is equivalent to
implementation('org.slf4j:slf4j-api') {
version {
strictly '[1.7, 1.8['
prefer '1.7.25'
}
}
}
上面的符號 [1.7, 1.8[!!1.7.25
等同於
-
strictly [1.7, 1.8[
-
prefer 1.7.25
這表示引擎必須選擇介於 1.7
(包含)和 1.8
(排除)之間的版本。如果圖形中沒有其他組件需要不同的版本,則應偏好 1.7.25
。
嚴格版本無法升級,並覆蓋任何傳遞相依性版本,因此建議將範圍與嚴格版本一起使用。 |
下表說明了幾個用例
此相依性的哪些版本是可接受的? |
|
|
|
|
選擇結果 |
---|---|---|---|---|---|
已使用版本 |
1.5 |
任何從 |
|||
已使用 |
[1.0, 2.0[ |
1.5 |
介於 |
||
已使用 |
[1.0, 2.0[ |
1.5 |
介於 |
||
與上述相同,但已知 |
[1.0, 2.0[ |
1.5 |
1.4 |
介於 |
|
沒有意見,適用於 |
1.5 |
如果沒有其他意見,則為 |
|||
沒有意見,偏好最新發行版本。 |
|
建置時的最新發行版本。 |
|||
在邊緣,最新發行版本,不降級。 |
|
建置時的最新發行版本。 |
|||
除了 |
1.5 |
|
|||
|
[1.5,1.6[ |
最新的 |
在函式庫中使用 strictly
需要仔細考慮,因為它會影響下游使用者。但是,當正確使用時,它可以幫助使用者了解哪些函式庫組合在其上下文中可能不相容。有關更多詳細資訊,請參閱關於 覆蓋相依性版本 的章節。
豐富版本資訊保留在 Gradle 模組元資料格式中。但是,將此資訊轉換為 Ivy 或 Maven 元資料格式會造成資訊遺失。最高層級的版本宣告— |
支持嚴格版本
Gradle 通過選擇在相依性圖形中找到的最大版本來解決任何相依性版本衝突。某些專案可能需要偏離預設行為,並強制執行較早版本的相依性,例如,如果專案的原始碼依賴於比某些外部函式庫更舊的相依性 API。
一般來說,強制相依性是為了降級相依性。降級有一些常見的用例
-
在最新發行版本中發現了一個錯誤。
-
您的程式碼依賴於與較新版本不二進位相容的舊版本。
-
您的程式碼不使用需要較新版本的函式庫部分。
強制執行相依性的版本需要仔細考慮,因為如果外部函式庫期望不同的版本,則更改傳遞相依性的版本可能會導致運行時錯誤。如果可能,通常最好升級您的原始碼以與較新版本相容。 |
假設一個專案使用 HttpClient
函式庫 執行 HTTP 呼叫。HttpClient
引入 Commons Codec
作為傳遞相依性,版本為 1.10
。但是,專案的生產原始碼需要 Commons Codec
1.9
的 API,該 API 在 1.10
中不再可用。可以通過在建置腳本中將相依性版本宣告為 strict
來強制執行
dependencies {
implementation("org.apache.httpcomponents:httpclient:4.5.4")
implementation("commons-codec:commons-codec") {
version {
strictly("1.9")
}
}
}
dependencies {
implementation 'org.apache.httpcomponents:httpclient:4.5.4'
implementation('commons-codec:commons-codec') {
version {
strictly '1.9'
}
}
}
使用嚴格版本的後果
必須仔細考慮使用嚴格版本
-
對於函式庫作者:嚴格版本實際上就像強制版本。它們優先於傳遞相依性,並覆蓋任何以傳遞方式找到的其他嚴格版本。如果消費者專案需要不同的版本,這可能會導致建置失敗。
-
對於消費者:在解析期間,嚴格版本被視為全域性的。如果嚴格版本與消費者的版本要求衝突,則會觸發解析錯誤。
例如,如果專案 B
strictly
依賴於 C:1.0
,但消費者專案 A 需要 C:1.1
,則會發生解析錯誤。
為了避免這種情況,建議使用版本範圍以及這些範圍內的偏好版本。
例如,B
可能會說,而不是 strictly 1.0
,它嚴格依賴 [1.0, 2.0[
範圍,但偏好 1.0
。然後,如果消費者選擇 1.1
(或範圍內的任何其他版本),建置將不再失敗。
不宣告版本
對於較大的專案,建議不宣告版本來宣告相依性,並使用 平台 管理版本
dependencies {
implementation("org.springframework:spring-web")
}
dependencies {
constraints {
implementation("org.springframework:spring-web:5.0.2.RELEASE")
}
}
dependencies {
implementation 'org.springframework:spring-web'
}
dependencies {
constraints {
implementation 'org.springframework:spring-web:5.0.2.RELEASE'
}
}
這種方法集中管理版本,包括傳遞相依性。
宣告動態版本
在許多情況下,您可能需要使用特定模組相依性的最新版本,或版本範圍內的最新版本。這在開發期間或在建立需要與各種相依性版本相容的函式庫時通常是必要的。專案可能會採用更積極的方法來使用相依性,方法是始終整合最新版本以存取尖端功能。
您可以通過使用動態版本輕鬆管理這些不斷變化的相依性。動態版本可以是版本範圍(例如,2.+
)或最新可用版本的佔位符(例如,latest.integration
)
plugins {
`java-library`
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework:spring-web:5.+")
}
plugins {
id 'java-library'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework:spring-web:5.+'
}
使用動態版本和變更模組可能會導致無法重現的建置。隨著模組的新版本發布,其 API 可能會與您的原始碼不相容。因此,請謹慎使用此功能。
宣告變更版本
團隊可能會在發布應用程式或函式庫的新版本之前實作一系列功能。一種常見的策略是允許消費者盡早整合其 artifact 的未完成版本,即發布具有變更版本的模組。變更版本表示功能集仍在積極開發中,並且尚未發布用於一般可用性的穩定版本。
在 Maven 儲存庫中,變更版本通常稱為 快照版本。快照版本包含後綴 -SNAPSHOT
。
以下範例示範如何在 Spring 相依性上宣告快照版本
plugins {
`java-library`
}
repositories {
mavenCentral()
maven {
url = uri("https://repo.spring.io/snapshot/")
}
}
dependencies {
implementation("org.springframework:spring-web:5.0.3.BUILD-SNAPSHOT")
}
plugins {
id 'java-library'
}
repositories {
mavenCentral()
maven {
url = 'https://repo.spring.io/snapshot/'
}
}
dependencies {
implementation 'org.springframework:spring-web:5.0.3.BUILD-SNAPSHOT'
}
Gradle 非常靈活,可以將任何版本視為變更版本。您只需將屬性 ExternalModuleDependency.setChanging(boolean) 設置為 true
即可。