依赖约束的功能类似于依赖项,主要区别在于它们本身不引入依赖关系。相反,约束定义版本要求,当通过其他方式将依赖项引入项目时,这些要求会影响解析过程。
尽管默认情况下约束不是严格版本,但如果需要,您可以指定严格版本约束。一旦包含依赖项,约束指定的版本将参与冲突解决,就像它是作为直接依赖项声明的一样。
在开发单项目库时,约束可以直接与直接依赖项一起声明。但是,在开发多项目库和应用程序时,最好在平台中集中声明依赖项
plugins {
`java-platform`
}
dependencies {
constraints {
// Platform declares some versions of libraries used in subprojects
api("commons-httpclient:commons-httpclient:3.1")
api("org.apache.commons:commons-lang3:3.8.1")
}
}
plugins {
id 'java-platform'
}
dependencies {
constraints {
// Platform declares some versions of libraries used in subprojects
api 'commons-httpclient:commons-httpclient:3.1'
api 'org.apache.commons:commons-lang3:3.8.1'
}
}
一般来说,依赖项分为直接依赖项或传递依赖项
-
直接依赖项是在组件的构建或元数据中显式指定的依赖项。
-
传递依赖项不是直接指定的;它们作为直接依赖项的依赖项自动引入。
组件可能需要直接依赖项和传递依赖项才能编译或运行。
声明约束与直接依赖项并存
依赖约束允许您为特定依赖项定义版本或版本范围,无论何时在解析过程中遇到该依赖项。
这是跨多个配置或项目管理组件版本的首选方法。
当 Gradle 解析模块版本时,它会考虑所有相关因素,包括富版本、传递依赖项和该模块的依赖约束。选择满足所有条件的最高版本。如果不存在这样的版本,Gradle 将失败并显示错误,详细说明冲突的声明。
在这种情况下,您可以调整依赖项声明、依赖约束,或对传递依赖项进行必要的更改。
与依赖项声明一样,依赖约束也按配置范围划分,允许您选择性地将它们应用于构建的特定部分。
constraints{}
代码块在 dependencies{}
代码块中用于声明这些约束
plugins {
`java-platform`
}
dependencies {
constraints {
api("commons-httpclient:commons-httpclient:3.1")
runtime("org.postgresql:postgresql:42.2.5")
}
}
plugins {
id 'java-platform'
}
dependencies {
constraints {
api 'commons-httpclient:commons-httpclient:3.1'
runtime 'org.postgresql:postgresql:42.2.5'
}
}
-
api("commons-httpclient:commons-httpclient:3.1")
:-
此行在
api
配置上创建一个约束,断言如果任何可解析的配置扩展了api
配置而解析commons-httpclient
,则其版本必须为3.1
或更高版本。 -
如果传递依赖项(依赖项的依赖项)或项目中的另一个模块引入了不同版本的
commons-httpclient
,Gradle 将强制依赖项解析为至少版本3.1
。 -
此约束确保库
commons-httpclient
在扩展api
配置的所有配置中都至少为版本3.1
。
-
-
runtime("org.postgresql:postgresql:42.2.5")
:-
同样,此行在
runtime
配置上应用约束,强制org.postgresql:postgresql
必须解析为至少版本42.2.5
。 -
即使项目中的其他依赖项或模块尝试引入不同版本的
postgresql
,Gradle 也会选择42.2.5
和其他声明版本中较高的版本。 -
这确保了对
postgresql
的任何运行时依赖项都将在扩展runtime
配置的所有可解析配置中解析为至少版本42.2.5
。
-
在传递依赖项上添加约束
依赖管理问题通常由传递依赖项引起。开发人员有时会错误地通过添加直接依赖项来解决这些问题,而不是使用约束正确处理它们。
依赖约束允许您控制传递依赖项的选择。
在以下示例中,仅当 commons-codec
作为传递依赖项引入时,commons-codec:1.11
的版本约束才适用,因为它未在项目中直接声明为依赖项。如果 commons-codec
未以传递方式引入,则约束无效
dependencies {
implementation("org.apache.httpcomponents:httpclient")
constraints {
implementation("org.apache.httpcomponents:httpclient:4.5.3") {
because("previous versions have a bug impacting this application")
}
implementation("commons-codec:commons-codec:1.11") {
because("version 1.9 pulled from httpclient has bugs affecting this application")
}
}
}
dependencies {
implementation 'org.apache.httpcomponents:httpclient'
constraints {
implementation('org.apache.httpcomponents:httpclient:4.5.3') {
because 'previous versions have a bug impacting this application'
}
implementation('commons-codec:commons-codec:1.11') {
because 'version 1.9 pulled from httpclient has bugs affecting this application'
}
}
}
仅在使用Gradle 模块元数据时才发布依赖约束。这意味着仅当发布和使用模块都使用 Gradle 时,它们才得到完全支持。如果模块与 Maven 或 Ivy 一起使用,则约束可能不会被保留。 |
依赖约束是传递的。如果 library A
依赖于 library B
,并且 library B
声明了对 module C
的约束,则该约束将影响 library A
依赖的 module C
的版本。
例如,如果 library A
依赖于 module C 版本 2
,但 library B
声明了对 module C 版本 3
的约束,则 library A
将解析 module C 的版本 3
。