平台和版本目录都有助于在项目中管理依赖版本,但它们服务于不同的目的,并且对依赖解析有不同的影响
版本目录
-
目的: 版本目录集中和标准化依赖坐标(group, name, version),并在构建脚本中提供类型安全的访问器,使依赖更易于管理。
-
对依赖图的影响: 版本目录不直接影响依赖解析。目录中定义的版本必须在
dependencies
块中显式引用,一旦引用,它们的行为与任何本地声明的依赖相同。此外,目录的内容对下游消费者透明,这意味着消费者无法识别依赖是本地声明的还是来自目录。
libs.versions.toml
[libraries]
mylib = { group = "com.example", name = "mylib", version = "1.0.0" }
平台
-
目的: 平台是依赖图中的一个模块,用于强制或对齐依赖(包括传递性依赖)的版本。它影响依赖解析,并确保不同模块间的版本一致性。
-
对依赖图的影响: 平台应用或强制依赖使用其声明的版本(即使本地声明时未指定版本)。平台中的这些版本通过依赖图传播,影响传递性依赖和下游消费者。它们是依赖图的正式组成部分,并可以在解析过程中决定最终选择的版本。
build.gradle.kts
plugins {
`java-platform`
}
dependencies {
constraints {
api("com.example:mylib:2.0.0")
}
}
在平台中使用版本目录
即使版本目录为某个依赖定义了版本,如果其他组件(例如平台或传递性依赖)建议使用不同版本,Gradle在解析时可能会选择不同的版本(除非使用了enforcedPlatform
)。
例如,版本目录可能将mylib
定义为版本1.0.0
,但如果平台强制使用2.0.0
,Gradle将选择版本2.0.0
。
为了确保一致的版本对齐,一种好的方法是使用版本目录来定义依赖版本,并结合平台来强制执行这些版本。
版本目录
gradle/libs.versions.toml
[versions]
junit-jupiter = "5.10.3"
[libraries]
guava = { module = "com.google.guava:guava"}
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
junit-jupiter-launcher = { module = "org.junit.platform:junit-platform-launcher" }
平台
platform/build.gradle.kts
plugins {
`java-platform`
}
javaPlatform {
allowDependencies()
}
dependencies {
constraints {
api("org.junit.jupiter:junit-jupiter:5.11.1") // Enforcing specific version
api("com.google.guava:guava:[33.1.0-jre,)") // Enforcing version range
}
}
platform/build.gradle
plugins {
id 'java-platform'
}
javaPlatform {
allowDependencies()
}
dependencies {
constraints {
api 'org.junit.jupiter:junit-jupiter:5.11.1' // Enforcing specific version
api 'com.google.guava:guava:[33.1.0-jre,)' // Enforcing version range
}
}
消费者
consumer/build.gradle.kts
dependencies {
// Platform
implementation(platform(project(":platform")))
// Catalog
testImplementation(libs.junit.jupiter)
testRuntimeOnly(libs.junit.jupiter.launcher)
implementation(libs.guava)
}
consumer/build.gradle
dependencies {
// Platform
implementation platform(project(":platform"))
// Catalog
testImplementation libs.junit.jupiter
testRuntimeOnly libs.junit.jupiter.launcher
implementation libs.guava
}
使用版本目录和平台的最佳实践
-
使用版本目录定义和跨项目共享依赖坐标。它们使依赖声明更一致且易于管理,但不保证版本对齐。
-
使用平台当你需要影响或强制模块间的版本对齐时。平台确保依赖解析到期望的版本,特别是在大型或多模块项目中。