直接相依性和相依性約束

一個元件可能具有兩種不同的相依性

  • 直接相依性是元件直接需要的。直接相依性也稱為第一層相依性。例如,如果專案原始程式碼需要 Guava,Guava 應宣告為直接相依性

  • 傳遞相依性是元件需要的相依性,但僅因為另一個相依性需要它們。

相依性管理問題通常與傳遞相依性有關。開發人員經常透過新增直接相依性來錯誤修正傳遞相依性問題。為避免此問題,Gradle 提供了相依性約束的概念。

對傳遞相依性新增約束

相依性約束讓您可以定義在建置指令碼中宣告的相依性與傳遞相依性的版本或版本範圍。這是表達應套用至組態的所有相依性的約束之建議方法。當 Gradle 嘗試將相依性解析至模組版本時,所有 具有版本的相依性宣告、所有傳遞相依性以及該模組的所有相依性約束都會納入考量。會選取符合所有條件的最高版本。如果找不到這樣的版本,Gradle 會失敗,並顯示衝突宣告的錯誤。如果發生這種情況,您可以調整您的相依性或相依性約束宣告,或視需要對傳遞相依性進行其他調整。與相依性宣告類似,相依性約束宣告會 依組態為範圍,因此可以針對建置的部分選擇性定義。如果相依性約束影響解析結果,任何類型的 相依性解析規則 仍可以在之後套用。

build.gradle.kts
dependencies {
    implementation("org.apache.httpcomponents:httpclient")
    constraints {
        implementation("org.apache.httpcomponents:httpclient:4.5.3") {
            because("previous versions have a bug impacting this application")
        }
        implementation("commons-codec:commons-codec:1.11") {
            because("version 1.9 pulled from httpclient has bugs affecting this application")
        }
    }
}
build.gradle
dependencies {
    implementation 'org.apache.httpcomponents:httpclient'
    constraints {
        implementation('org.apache.httpcomponents:httpclient:4.5.3') {
            because 'previous versions have a bug impacting this application'
        }
        implementation('commons-codec:commons-codec:1.11') {
            because 'version 1.9 pulled from httpclient has bugs affecting this application'
        }
    }
}

在範例中,所有版本都從相依性宣告中省略。相反地,版本會在約束區塊中定義。commons-codec:1.11 的版本定義僅在 commons-codec 作為傳遞相依性引入時才會納入考量,因為 commons-codec 未在專案中定義為相依性。否則,約束不會產生任何效果。相依性約束也可以定義 豐富版本約束,並支援 嚴格版本,以強制執行版本,即使它與傳遞相依性定義的版本相矛盾(例如,如果需要降級版本)。

僅在使用 Gradle 模組元資料 時才會發布相依性約束。這表示目前僅在使用 Gradle 進行發布和使用時才會完全支援(例如,在使用 Maven 或 Ivy 使用模組時會「遺失」)。

相依性約束本身也可以傳遞方式新增。