在 Gradle,如何在一个地方声明共同的附属关系?

在 Maven 中有一个非常有用的特性,您可以在父 POM 的 <dependencyManagement>部分中定义一个依赖项,并从子模块中引用该依赖项,而不需要指定版本或范围或其他任何东西。

Gradle 还有什么选择?

47649 次浏览

可以在父脚本中声明公共依赖项:

ext.libraries = [ // Groovy map literal
spring_core: "org.springframework:spring-core:3.1",
junit: "junit:junit:4.10"
]

然后,您可以从子脚本使用依赖项声明,如下所示:

dependencies {
compile libraries.spring_core
testCompile libraries.junit
}

To share dependency declarations with advanced configuration options, you can use DependencyHandler.create:

libraries = [
spring_core: dependencies.create("org.springframework:spring-core:3.1") {
exclude module: "commons-logging"
force = true
}
]

Multiple dependencies can be shared under the same name:

libraries = [
spring: [ // Groovy list literal
"org.springframework:spring-core:3.1",
"org.springframework:spring-jdbc:3.1"
]
]

然后,dependencies { compile libraries.spring }将同时添加这两个依赖项。

您不能以这种方式共享的一个信息是应该将依赖项分配给哪个配置(用 Maven 术语来说是 范围)。然而,根据我的经验,无论如何,最好是明确地说明这一点。

这是一个迟到的回复,但是你可能也想看看: < a href = “ http://plugins.gradle.org/plugin/io.spring.Depency-management”rel = “ norefrer”> http://plugins.gradle.org/plugin/io.spring.dependency-management It provides possibility to import a maven 'bom', and reuse the definitions defined in the 'bom'. 当逐渐从一个专家转移到另一个专家的时候,这当然是一个很好的帮助! 现在就享受它吧。

io.spring.gradle:dependency-management-plugin插件有问题,新的 Gradle 3. x 系列,但稳定的2. x 系列。请参考错误报告 放弃对3年级的支持 # 115

如果是 Spring (BOM 使用的主要推动者) ,你可以用:

buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:1.0.0.RELEASE'
}
}


repositories {
mavenLocal()
jcenter()
}


apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'


dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:Athens-SR3'
}
}


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


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

请注意,io.spring.platform:platform-bomorg.springframework.boot:spring-boot-starter-parent作为父级,因此它与 SpringBoot 是兼容的

You can verify actual dependency resolution via:

$ gradle dependencies
$ gradle dependencies --configuration compile
$ gradle dependencies -p $SUBPROJ


$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

or with task:

task showMeCache {
configurations.compile.each { println it }
}

阅读官方 Soring 博客文章 更好的 GRADE 依赖管理,了解引入 io.spring.gradle:dependency-management-plugin的原因。

你可以使用下面的代码 集中一个依赖项:

In gradle.properties

COMPILE_SDK_VERSION=26
BUILD_TOOLS_VERSION=26.0.1
TARGET_SDK_VERSION=26
MIN_SDK_VERSION=14


ANDROID_SUPPORT_VERSION=26.0.2

在每个模块中添加到 build.gradle:

android {
compileSdkVersion COMPILE_SDK_VERSION as int
buildToolsVersion BUILD_TOOLS_VERSION as String


defaultConfig {
minSdkVersion MIN_SDK_VERSION as int
targetSdkVersion TARGET_SDK_VERSION as int
versionCode 1
versionName "1.0"


}


}


dependencies {
compile "com.android.support:appcompat-v7:${ANDROID_SUPPORT_VERSION}"
compile "com.android.support:support-v4:${ANDROID_SUPPORT_VERSION}"
compile "com.android.support:support-annotations:${ANDROID_SUPPORT_VERSION}"
compile "com.android.support:support-vector-drawable:${ANDROID_SUPPORT_VERSION}"
compile "com.android.support:design:${ANDROID_SUPPORT_VERSION}"
}

This blog post suggest managing dependencies and groups as configurations: Https://www.javacodegeeks.com/2016/05/manage-dependencies-gradle-multi-project-build.html

我自己没有试过,但看起来很有趣。

根项目构建,级别

subprojects {
configurations {
commonsIo
}


dependencies {
commonsIo 'commons-io:commons-io:2.5'
}
}

子项目建设,分级

configurations {
compile.extendsFrom commonsIo
}

从4.6级开始,文档中建议使用依赖约束来实现这一点:

对于大型项目,推荐的做法是声明不带版本的依赖关系,并使用依赖关系约束进行版本声明。这样做的好处是,依赖关系约束允许您在一个地方管理所有依赖关系的版本,包括可传递的版本。

在您的父 build.gradle文件中:

allprojects {
plugins.withType(JavaPlugin).whenPluginAdded {
dependencies {
constraints {
implementation("com.google.guava:guava:27.0.1-jre")
}
}
}
}

用 Java 插件(... whenPluginAdded {)检查来包装依赖块并不是必需的,但是它会处理向同一个构建中添加非 Java 项目的问题。

然后,在一个儿童年级项目中,你可以简单地省略这个版本:

apply plugin: "java"


dependencies {
implementation("com.google.guava:guava")
}

子版本仍然可以选择指定更高的版本。如果指定了较低的版本,则会自动升级到约束中的版本。

To keep you gradle file clean, we can group dependency in an array and implement them later.

  1. 在依赖块之外的 build.gradle (应用程序级别)中添加这样的库版本:

//声明库的版本

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. 创建一个相关依赖项的数组,这样以后就可以很容易地找到它:

//在库中使用版本,并在访问时添加依赖项 名称(如改装(第一个))

final networkDependencies = [
retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]
  1. 附属块:

//实现数组中的所有依赖项

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])


implementation networkDependencies.values()
}

所以 最终代码会是这样的:

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'


final networkDependencies = [
retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]


dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])


implementation networkDependencies.values()
}

我更喜欢在根项目中创建包含内容的 共同依赖关系文件

buildscript {
ext {
commonDependencies = [
redis      : 'redis.clients:jedis:3.6.3',
lettuce    : 'io.lettuce:lettuce-core:6.1.4.RELEASE'
]
}
}

然后在根/子模块的 build.gradle

apply from: rootProject.file("common_dependencies.gradle")


dependencies {
commonDependencies.values().forEach {
implementation it
}
}

正如 数据他们的回答中所说,Gradle 现在有一个叫版本目录的东西。
下面是 Kotlin DSL(* . kts 文件)的一个示例。

设置,等级,等级中定义依赖项:

// Configure dependencies aspects applied to all projects
dependencyResolutionManagement {
// By default, repositories declared by a project will override the ones here.
// You can change this behavior with the repositoriesMode property.
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)


// Define repositories for all projects
repositories {
mavenCentral()
maven("https://jitpack.io")
}


versionCatalogs {
create("libs") {
// Versions are useful specially when you have libraries with the same
// group and version which are updated together with the same version
version("room", "2.4.1")
//       │       │
//       │       └───> The version notation
//       └───> Your desired name (alias)
    

library("material", "com.google.android.material:material:1.4.0")
//       │           │
//       │           └───> The dependency notation (coordinates)
//       ├───> Your desired name (alias); only letters, digits and _ - .
//       └───> Note that _ - . will all be normalized to .
    

// You can configure the version as you would in a regular build file
// Note that the group and module are separate parameters
library("junit5", "org.junit.jupiter", "junit-jupiter").version {
prefer("5.8.0")
}
    

// Using the same version for multiple dependencies
library("room-ktx", "androidx.room", "room-ktx").versionRef("room")
library("room-runtime", "androidx.room", "room-runtime").versionRef("room")
}
}
}

Build.gradle.kts中的用法:

dependencies {
implementation(libs.material)
implementation(libs.room.ktx)
implementation(libs.room.runtime)
testImplementation(libs.junit5)
}

如您所见,不仅可以声明依赖项,还可以在这里声明存储库(而不是在顶级构建脚本中使用 allprojects块为所有子项目定义存储库)。

有关上述解决方案的常规语法以及有关版本目录和集中存储库和依赖项配置的更多信息,请参见 分级官方指南