相依性類型

Gradle 中有三種主要類型的相依性

  1. 模組相依性:參照來自外部儲存庫的函式庫。

  2. 專案相依性:參照在同一個多專案建置中的其他專案。

  3. 檔案相依性:參照本機檔案或目錄,例如 .jar.aar 檔案。

1. 模組相依性

模組相依性是最常見的相依性。它們參照由模組座標(群組、名稱和版本)識別的相依性

build.gradle.kts
dependencies {
    runtimeOnly(group = "org.springframework", name = "spring-core", version = "2.5")
    runtimeOnly("org.springframework:spring-aop:2.5")
    runtimeOnly("org.hibernate:hibernate:3.0.5") {
        isTransitive = true
    }
    runtimeOnly(group = "org.hibernate", name = "hibernate", version = "3.0.5") {
        isTransitive = true
    }
}
build.gradle
dependencies {
    runtimeOnly group: 'org.springframework', name: 'spring-core', version: '2.5'
    runtimeOnly 'org.springframework:spring-core:2.5',
            'org.springframework:spring-aop:2.5'
    runtimeOnly(
        [group: 'org.springframework', name: 'spring-core', version: '2.5'],
        [group: 'org.springframework', name: 'spring-aop', version: '2.5']
    )
    runtimeOnly('org.hibernate:hibernate:3.0.5') {
        transitive = true
    }
    runtimeOnly group: 'org.hibernate', name: 'hibernate', version: '3.0.5', transitive: true
    runtimeOnly(group: 'org.hibernate', name: 'hibernate', version: '3.0.5') {
        transitive = true
    }
}

Gradle 提供多種表示法來宣告模組相依性,包括字串表示法和映射表示法。

  • 字串表示法: 通過將群組、名稱和版本組合到單個字串中,簡化了相依性宣告。

  • 映射表示法: 允許單獨指定座標的每個部分。

對於進階配置,例如強制執行嚴格版本,您也可以在這些表示法旁邊提供閉包。

2. 專案相依性

專案相依性允許您參照多專案 Gradle 建置中的其他專案。

dependency management project dependencies

這對於將大型專案組織成更小的模組化組件非常有用

web-service/build.gradle.kts
dependencies {
    implementation(project(":utils"))
    implementation(project(":api"))
}
web-service/build.gradle
dependencies {
    implementation project(':utils')
    implementation project(':api')
}

Gradle 使用 project() 函數來定義專案相依性。此函數採用目標專案在建置中的相對路徑。路徑通常使用冒號 (:) 來分隔專案結構的不同層級。

專案相依性會自動解析,以便始終在依賴專案之前建置相關專案。

型別安全專案相依性

型別安全專案存取器是一項孵化中的功能,必須明確啟用。實作可能會隨時更改。

要添加對型別安全專案存取器的支援,請將 enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 添加到您的 settings.gradle(.kts) 檔案中

settings.gradle.kts
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
settings.gradle
enableFeaturePreview 'TYPESAFE_PROJECT_ACCESSORS'

使用 project(":some:path") 表示法的一個缺點是需要記住相依性的專案路徑。此外,更改專案路徑需要手動更新每個出現的地方,從而增加了遺漏的風險。

相反,實驗性的型別安全專案存取器 API 提供了 IDE 完成功能,使宣告相依性更容易

web-service/build.gradle.kts
dependencies {
    implementation(projects.utils)
    implementation(projects.api)
}
web-service/build.gradle
dependencies {
    implementation projects.utils
    implementation projects.api
}

使用此 API,在 Kotlin DSL 腳本中錯誤指定的專案會觸發編譯錯誤,幫助您避免遺漏更新。

專案存取器基於專案路徑。例如,路徑 :commons:utils:some:lib 變為 projects.commons.utils.some.lib,而 kebab-case (some-lib) 和 snake-case (some_lib) 則轉換為 camel case:projects.someLib

3. 檔案相依性

檔案相依性允許您通過參照外部 JAR 或其他檔案的路徑,將它們直接包含到您的專案中。檔案相依性還允許您將一組檔案直接添加到配置中,而無需使用儲存庫。

通常不鼓勵使用檔案相依性。相反,首選宣告外部儲存庫上的相依性,或者在必要時,使用 file:// URL 宣告 maven 或 ivy 儲存庫。
dependency management file dependencies

檔案相依性是獨特的,因為它們表示對檔案系統上檔案的直接參照,而沒有任何相關聯的 元數據,例如傳遞相依性、來源或作者資訊。

build.gradle.kts
configurations {
    create("antContrib")
    create("externalLibs")
    create("deploymentTools")
}

dependencies {
    "antContrib"(files("ant/antcontrib.jar"))
    "externalLibs"(files("libs/commons-lang.jar", "libs/log4j.jar"))
    "deploymentTools"(fileTree("tools") { include("*.exe") })
}
build.gradle
configurations {
    antContrib
    externalLibs
    deploymentTools
}

dependencies {
    antContrib files('ant/antcontrib.jar')
    externalLibs files('libs/commons-lang.jar', 'libs/log4j.jar')
    deploymentTools(fileTree('tools') { include '*.exe' })
}

在此範例中,每個相依性都明確指定了其在檔案系統中的位置。參照這些檔案的常用方法包括

即使在同一台電腦上,FileTree 中檔案的順序也不能保證是穩定的。因此,使用 FileTree 的相依性配置可能會產生順序不同的解析結果,這可能會影響使用這些結果作為輸入的任務的可快取性。為了確保更可預測和穩定的行為,建議在可能的情況下使用更簡單的 files 方法。

或者,您可以使用 平面目錄 儲存庫來指定多個檔案相依性的來源目錄。

理想情況下,您應該使用具有本機 URL 的 Maven 或 Ivy 儲存庫

repositories {
    maven {
        url = 'file:///path/to/local/files' // Replace with your actual path
    }
}

要將檔案添加為相依性,請將 檔案集合 傳遞到配置

build.gradle.kts
dependencies {
    runtimeOnly(files("libs/a.jar", "libs/b.jar"))
    runtimeOnly(fileTree("libs") { include("*.jar") })
}
build.gradle
dependencies {
    runtimeOnly files('libs/a.jar', 'libs/b.jar')
    runtimeOnly fileTree('libs') { include '*.jar' }
}

請注意,檔案相依性不包含在您專案的已發布相依性描述符中。但是,它們在同一建置中的傳遞相依性中可用,這意味著它們可以在目前的建置中使用,但不能在外部使用。

您應該指定哪些任務產生檔案相依性的檔案。否則,當您從另一個專案傳遞依賴它們時,必要的任務可能不會執行

build.gradle.kts
dependencies {
    implementation(files(layout.buildDirectory.dir("classes")) {
        builtBy("compile")
    })
}

tasks.register("compile") {
    doLast {
        println("compiling classes")
    }
}

tasks.register("list") {
    val compileClasspath: FileCollection = configurations["compileClasspath"]
    dependsOn(compileClasspath)
    doLast {
        println("classpath = ${compileClasspath.map { file: File -> file.name }}")
    }
}
build.gradle
dependencies {
    implementation files(layout.buildDirectory.dir('classes')) {
        builtBy 'compile'
    }
}

tasks.register('compile') {
    doLast {
        println 'compiling classes'
    }
}

tasks.register('list') {
    FileCollection compileClasspath = configurations.compileClasspath
    dependsOn compileClasspath
    doLast {
        println "classpath = ${compileClasspath.collect { File file -> file.name }}"
    }
}
$ gradle -q list
compiling classes
classpath = [classes]

Gradle 發行版本特定的相依性

Gradle API 相依性

您可以使用 DependencyHandler.gradleApi() 方法宣告對目前 Gradle 版本 API 的相依性。當您開發自訂 Gradle 任務或外掛程式時,這非常有用

build.gradle.kts
dependencies {
    implementation(gradleApi())
}
build.gradle
dependencies {
    implementation gradleApi()
}

Gradle TestKit 相依性

您可以使用 DependencyHandler.gradleTestKit() 方法宣告對目前 Gradle 版本 TestKit API 的相依性。這對於為 Gradle 外掛程式和建置腳本編寫和執行功能測試非常有用

build.gradle.kts
dependencies {
    testImplementation(gradleTestKit())
}
build.gradle
dependencies {
    testImplementation gradleTestKit()
}

本機 Groovy 相依性

您可以使用 DependencyHandler.localGroovy() 方法宣告對 Gradle 發行的 Groovy 的相依性。當您在 Groovy 中開發自訂 Gradle 任務或外掛程式時,這非常有用

build.gradle.kts
dependencies {
    implementation(localGroovy())
}
build.gradle
dependencies {
    implementation localGroovy()
}

文件化相依性

當宣告相依性或 相依性約束 時,您可以提供原因來闡明包含相依性的原因。這有助於使您的建置腳本和 相依性洞察報告 更容易理解

build.gradle.kts
plugins {
    `java-library`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.ow2.asm:asm:7.1") {
        because("we require a JDK 9 compatible bytecode generator")
    }
}
build.gradle
plugins {
    id 'java-library'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation('org.ow2.asm:asm:7.1') {
        because 'we require a JDK 9 compatible bytecode generator'
    }
}

在此範例中,because() 方法提供了包含 asm 函式庫的原因,這有助於解釋其在建置上下文中的用途

$ gradle -q dependencyInsight --dependency asm
org.ow2.asm:asm:7.1
  Variant compile:
    | Attribute Name                 | Provided | Requested    |
    |--------------------------------|----------|--------------|
    | org.gradle.status              | release  |              |
    | org.gradle.category            | library  | library      |
    | org.gradle.libraryelements     | jar      | classes      |
    | org.gradle.usage               | java-api | java-api     |
    | org.gradle.dependency.bundling |          | external     |
    | org.gradle.jvm.environment     |          | standard-jvm |
    | org.gradle.jvm.version         |          | 11           |
   Selection reasons:
      - Was requested: we require a JDK 9 compatible bytecode generator

org.ow2.asm:asm:7.1
\--- compileClasspath

A web-based, searchable dependency report is available by adding the --scan option.