更好的 Gradle 相依性管理

工程 | Andy Wilkinson | 2015年2月23日 | ...

Maven 的 相依性管理 包含物料清單 (bill-of-materials, bom) 的概念。Bom 是一種特殊的 pom,用於控制專案相依性的版本,並提供定義和更新這些版本的中心位置。

許多 Spring 專案 (包括 Spring Framework、Spring Cloud、Spring Boot 和 Spring IO Platform) 提供了 bom,以方便 Maven 使用者。不幸的是,如果您使用 Gradle,事情就沒那麼容易了。

Gradle 中的相依性管理

Gradle 的相依性管理 使用 ResolutionStrategy 來控制專案的相依性版本。這提供了很大的威力和靈活性,但沒有提供重用 Maven bom 中已宣告的相依性管理的方法。 因此,您必須手動執行。 根據 bom 的不同,這很容易在您的 build.gradle 腳本中額外增加數十行程式碼,僅僅是為了重用一些現有的設定。

在 Gradle 中重用 bom

Gradle 的主要優勢之一是它易於擴充,並且可以透過使用外掛程式來自訂其行為。 我們利用了這一點,並編寫了一個 用於 Gradle 的相依性管理外掛程式。 它與 Gradle 1.x 和 2.x 相容。 此外掛程式可讓您使用 Maven bom,以幾行程式碼控制組建的相依性。 第一步是套用外掛程式

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath "io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE"
  }
}

apply plugin: "io.spring.dependency-management"

套用此外掛程式後,您可以使用它來匯入 Maven bom

dependencyManagement {
  imports {
    mavenBom 'io.spring.platform:platform-bom:1.1.1.RELEASE'
  }
}

完成此設定後,您可以宣告 bom 中任何內容的相依性,而無需指定版本

dependencies {
    compile 'org.springframework:spring-core'
}

匯入的 bom 將控制相依性的版本。 如果它們列在 bom 中,它也將控制其傳遞相依性的版本。

Gradle 中的排除

Gradle 可以從 Maven 儲存庫檢索相依性,並且它使用 Maven pom 檔案中的元資料來執行此操作。 但是,它不是遵守 Maven 的規則,而是將其自身略有不同的語意應用於元資料。 這可能導致問題的一個領域是排除傳遞相依性。 最好用一個簡單的例子來說明。

想像一個模組,它依賴於幾個 Spring Framework 模組,spring-corespring-beans,並且使用 SLF4J 而不是 Commons Logging。 其 pom 中的相依性如下所示

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.1.4.RELEASE</version>
  <exclusions>
    <exclusion>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>4.1.4.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.10</version>
</dependency>

如果 Maven 組建依賴於此模組,則其相依性樹如下所示

\- com.example:my-library:jar:0.0.1-SNAPSHOT:compile
   +- org.springframework:spring-core:jar:4.1.4.RELEASE:compile
   +- org.springframework:spring-beans:jar:4.1.4.RELEASE:compile
   \- org.slf4j:jcl-over-slf4j:jar:1.7.10:compile
      \- org.slf4j:slf4j-api:jar:1.7.10:compile

commons-logging 未列出,因為唯一依賴於它的模組是 spring-core,其中它已被排除。

等效的 Gradle 組建的相依性樹如下所示

\--- com.example:my-library:0.0.1-SNAPSHOT
     +--- org.springframework:spring-core:4.1.4.RELEASE
     |    \--- commons-logging:commons-logging:1.2
     +--- org.springframework:spring-beans:4.1.4.RELEASE
     |    \--- org.springframework:spring-core:4.1.4.RELEASE (*)
     \--- org.slf4j:jcl-over-slf4j:1.7.10
          \--- org.slf4j:slf4j-api:1.7.10

儘管有排除,但這次列出了 commons-logging。 這可能會產生問題,因為它會使您的類別路徑受到不應該存在的相依性的污染。 您可以透過在 Gradle 組建中手動設定所需的排除來解決此問題,但首先您必須知道應該排除哪些內容,然後您必須完成配置它們的繁瑣且容易出錯的過程。

尊重 pom 的排除

相依性管理外掛程式變更了 Gradle 對 pom 排除的處理方式,以便它們的行為與 Maven 中的行為相同。 透過將此外掛程式套用於範例專案,它不再提取 commons-logging

\--- com.example:my-library:0.0.1-SNAPSHOT
     +--- org.springframework:spring-core:4.1.4.RELEASE
     +--- org.springframework:spring-beans:4.1.4.RELEASE
     |    \--- org.springframework:spring-core:4.1.4.RELEASE
     \--- org.slf4j:jcl-over-slf4j:1.7.10
          \--- org.slf4j:slf4j-api:1.7.10

將此外掛程式與 Spring Boot 搭配使用

此外掛程式與 Spring Boot 的 Gradle 外掛程式之間有一些相似之處。 例如,Spring Boot 外掛程式也 允許在不指定版本的情況下宣告相依性,但是它不會影響傳遞相依性,也不會尊重 Maven 排除。

在即將推出的 Spring Boot 1.3 中,我們 移除了 Boot 自己的相依性管理,並開始改用相依性管理外掛程式。 對於早期版本的 Spring Boot 使用者,這兩個外掛程式可以完美地共存,您可以將相依性管理外掛程式設定為使用 Spring Boot 的 starter bom

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath "io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE"
    classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE"
  }
}

apply plugin: "io.spring.dependency-management"
apply plugin: "spring-boot"

repositories {
  jcenter()
}

dependencyManagement {
  imports {
    mavenBom 'org.springframework.boot:spring-boot-starter-parent:1.2.1.RELEASE'
  }
}

dependencies {
  compile "org.springframework.boot:spring-boot-starter-web"
}

了解更多

除了上述功能外,此外掛程式還支援使用 bom 的屬性 (包括覆寫它們和在您的 Gradle 組建中使用它們)、在 Gradle 產生的 pom 檔案中自動包含相依性管理元資料等等。 查看 README 以獲取更多詳細資訊。

此外掛程式已獲得 Apache 授權,並位於 GitHub 上。 GitHub 也用於 問題追蹤。 歡迎提出功能建議、提取請求和錯誤報告。

取得 Spring 電子報

與 Spring 電子報保持聯繫

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進度。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看全部