簡體   English   中英

如何避免在多模塊 Gradle 項目中重復依賴版本?

[英]How to avoid repeating dependency versions in a multi-module Gradle project?

這里有一個示例 Spring Boot 項目,其中包含兩個模塊。

其中一個模塊的build.gradle如下所示:

buildscript {
    ext { springBootVersion = '2.1.4.RELEASE' }
    repositories { mavenCentral() }
    dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }
}

plugins {
    id "io.spring.dependency-management" version "1.0.5.RELEASE"
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
    baseName = 'gs-multi-module-application'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8

repositories { mavenCentral() }

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile project(':library')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

另一個模塊的build.gradle看起來像這樣:

buildscript {
    repositories { mavenCentral() }
}

plugins { id "io.spring.dependency-management" version "1.0.5.RELEASE" }

ext { springBootVersion = '2.1.4.RELEASE' }

apply plugin: 'java'
apply plugin: 'eclipse'

jar {
    baseName = 'gs-multi-module-library'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8

repositories { mavenCentral() }

dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") }
}

兩個模塊中都聲明了springBootVersion = '2.1.4.RELEASE' 對於一個 2 模塊的項目來說這可能不是問題,但是如果我的項目有 10 個模塊並且我想確保所有模塊始終依賴於相同版本的 Spring Boot,那么重復這個版本會很不方便並且容易出錯在每個模塊中。

同樣,我可能想為這兩個模塊添加對commons-io的依賴,並確保它們始終依賴於相同版本的commons-io

如何避免在每個build.gradle文件中重復版本號?

您可以將ext{}塊移動到新文件,並通過apply from:語句在項目的build.gradle文件中引用它。

// project/versions.gradle
ext {
    springBootVersion = '2.1.4.RELEASE'
}

// project/build.gradle
buildscript {
    apply from: 'versions.gradle'
}

// module/build.gradle
dependencies {
    implementation "some.dependency:dependency:$springBootVersion"
}

現在,您只需在一個位置定義依賴項版本。

通常情況下,一個項目都會有一個項目級build.gradle除了文件模塊特定build.gradle文件。 但是,您共享的repo缺少項目級構建腳本。 這就是為什么在每個模塊的構建腳本中定義了ext{}塊。 這可能不是最優的,我建議查看其他回購,看看不同的開發人員如何解決這個問題。

請參閱此Gradle文檔Gradle中的一個好習慣是配置在一個地方共享共同特征的子項目,例如在root project的構建腳本中(或使用自定義插件)

在您從Spring引導文檔中獲取的示例中,可以應用此模式將Spring引導和其他常見依賴項版本集中在一個位置,但您可以更進一步並配置其他常見特性(Java插件配置,存儲庫等等)。

以下是我將如何重寫Spring示例以使其更干凈和干燥:

根項目

/**
 * Add Springboot plugin into build script classpath (without applying it)
 * This is this only place where you need to define the Springboot version.
 *
 * See https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#managing-dependencies-using-in-isolation
 */
plugins {
    id "org.springframework.boot" version "2.1.4.RELEASE" apply false
}

// Set version for dependencies share between subprojects
ext {
    commonsIoVersion = "2.6"
}

subprojects {
    // common config for all Java subprojects
    apply plugin: "java"
    apply plugin: "eclipse"
    sourceCompatibility = 1.8
    repositories { 
        mavenCentral() 
    }

    // apply Spring Boot's dependency management plugin
    apply plugin: "io.spring.dependency-management"
}

圖書館子項目

// no need for additional plugins

jar {
    baseName = 'gs-multi-module-library'
    version = '0.0.1-SNAPSHOT'
}

dependencies {
    implementation('org.springframework.boot:spring-boot-starter')
    implementation "commons-io:commons-io:${commonsIoVersion}"

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports {
        mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES 
    }
}

申請子項目

plugins {
    id "org.springframework.boot"
}

bootJar { 
    baseName = 'gs-multi-module-application'
    version = '0.0.1-SNAPSHOT'
}

dependencies {
    implementation  project(':library')

    implementation ('org.springframework.boot:spring-boot-starter-actuator')
    implementation ('org.springframework.boot:spring-boot-starter-web')
    implementation "commons-io:commons-io:${commonsIoVersion}"

    // could also be configured in root project.
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

筆記

  • 此解決方案僅使用新plugins {} DSL(不需要舊的buildscript塊)
  • 不應該顯式配置io.spring.dependency-management版本,它將從Spring啟動插件繼承

有一個 Gradle 一致的版本插件可以處理這個問題:

https://github.com/palantir/gradle-consistent-versions

在根build.gradle文件中設置此插件后,您將像這樣創建一個versions.props文件,以使用文檔中的示例。

com.fasterxml.jackson.*:jackson-* = 2.9.6
com.google.guava:guava = 21.0
com.squareup.okhttp3:okhttp = 3.12.0
junit:junit = 4.12
org.assertj:* = 3.10.0

還有一個versions.locks文件,它由./gradlew --write-locks自動生成。 然后,您可以在build.gradle文件中指定無版本依賴項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM