依赖约束的功能类似于依赖,其关键区别在于它们本身不引入依赖。相反,约束定义了版本要求,这些要求在依赖通过其他方式引入项目时影响解析过程。
尽管约束默认不是严格版本,但如果需要,您可以指定一个严格的版本约束。一旦包含依赖项,约束指定的版本将参与冲突解决,就像它被声明为直接依赖项一样。
在开发单项目库时,约束可以直接在直接依赖旁边声明。但是,在开发多项目库和应用程序时,最好在平台中集中声明依赖项
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配置上创建了一个约束,声明如果commons-httpclient被扩展api配置的可解析配置解析,其版本必须是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:1.11 的版本约束仅在 commons-codec 作为传递性依赖引入时适用,因为它未在项目中直接声明为依赖。如果 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 version 2,但 library B 声明了对 module C version 3 的约束,则 library A 将解析 version 3 of module C。