使用和配置存储库
Gradle 特别强调支持现有的存储库基础设施。 您已经了解了如何在构建中使用 Maven Central。 通过使用单个方法调用 mavenCentral(),您将构建配置为针对最流行的 Java 二进制存储库。 除了预配置的存储库支持之外,您还可以分配 Maven 或 Ivy 存储库的任意 URL,并根据需要将其配置为使用身份验证。 或者,可以使用简单的文件系统存储库来解决依赖性。 如果找到依赖项的元数据,也将从存储库下载它。 表 5.2 显示了不同类型的存储库以及下一步要了解更多信息的部分。
类型 | 描述 | 去哪里获取更多信息 |
---|---|---|
Maven仓库 |
本地文件系统或远程服务器上的 Maven 存储库,或预配置的 Maven Central |
参考章节 5.5.2 |
Ivy仓库 |
本地文件系统或远程服务器上具有特定布局模式的 Ivy 存储库 |
参考章节 5.5.3 |
Flat目录仓库 |
本地文件系统上的存储库,没有元数据支持 |
参考章节 5.5.4 |
请随意跳转到描述您要在项目中使用的存储库的部分。 在下一节中,我们将先了解 Gradle 对定义和配置存储库的 API 支持,然后再将它们应用到实际示例中。
了解存储库 API 表示
在项目中定义存储库的核心是接口 RepositoryHandler,它提供了添加各种类型存储库的方法。 在项目中,这些方法在您的 repositories 配置块中调用。 您可以声明多个存储库。 当依赖项管理器尝试下载依赖项及其元数据时,它会按照声明的顺序检查存储库。 首先提供依赖项的存储库获胜。 后续存储库声明将不会进一步检查特定依赖项。 如图 5.8 所示,每个存储库接口都公开特定于存储库类型的不同方法。
Gradle 不喜欢任何存储库类型。 根据您的项目的需要来声明最合适的存储库。 在下一节中,我们将了解声明 Maven 存储库的语法。
Maven仓库
Maven 存储库是 Java 项目中最常用的存储库类型之一。 该库通常以 JAR 文件的形式表示。 元数据以 XML 形式表示,描述了库及其传递依赖项(POM 文件)的相关信息。 这两个工件都存储在存储库中预定义的目录结构中。 当您在构建脚本中声明依赖项时,它的属性用于派生存储库中的确切位置。 依赖项的组属性中的点字符表示 Maven 存储库中的子目录。 图 5.9 显示了如何映射 Cargo Ant 依赖属性以确定 JAR 和 POM 文件在存储库中的位置。

RepositoryHandler 接口提供了两种方法,允许您定义预配置的 Maven 存储库。 mavenCentral() 方法将对 Maven Central 的引用添加到存储库列表中,mavenLocal() 方法引用文件系统中的本地 Maven 存储库。 让我们回顾一下这两种存储库类型并讨论何时在项目中使用它们。
添加预配置的 Maven 中央存储库
Maven Central 是构建中常用的存储库。 Gradle 希望让构建开发人员尽可能轻松,因此为您提供了声明 Maven Central 的快捷方式。 您不必每次都定义 URL http://repo1.maven.org/maven2 ,只需调用方法 mavenCentral() 即可,如以下代码片段所示:

repositories {
mavenCentral()
}
存在用于定义本地 Maven 存储库的类似快捷方式,默认情况下在 <USER_HOME>/.m2/repository 下可用。
添加预配置的本地 Maven 存储库
当 Gradle 解析依赖项时,它会位于存储库中,被下载,然后存储在本地缓存中。 此缓存在本地文件系统中的位置与 Maven 下载工件后存储工件的目录不同。 您可能想知道既然您正在使用 Gradle,何时需要使用本地 Maven 存储库。 如果您在构建工具的混合环境中工作,情况尤其如此。 想象一下,您正在开发一个使用 Maven 生成库的项目,而另一个使用 Gradle 运行的项目想要使用该库。 特别是在开发过程中,您将经历实施更改并在消费端尝试更改的周期。 为了防止您必须将库发布到远程 Maven 存储库以进行每一个小的更改,Gradle 为您提供了以本地 Maven 存储库为目标的选项,如以下存储库声明所示:
repositories {
mavenLocal()
}
请注意,使用本地 Maven 存储库应仅限于此特定用例,因为它可能会导致不可预见的副作用。 您明确依赖于仅在本地文件系统中可用的工件。 如果工件不存在,在其他计算机或持续集成服务器上运行脚本可能会导致构建失败。
添加自定义 Maven 存储库
您想要以 Maven Central 以外的存储库为目标有多种原因。 也许特定的依赖项根本不可用,或者您希望通过设置自己的企业存储库来确保构建的可靠性。 存储库管理器为您提供的选项之一是使用 Maven 布局配置存储库。 这意味着它遵循我们之前讨论的工件存储模式。 此外,您可以通过要求用户提供身份验证凭据来保护对存储库的访问。 Gradle 的 API 支持两种配置自定义存储库的方法:maven() 和 mavenRepo()。 以下清单显示了如果 Maven Central 中没有某个工件,如何定位替代公共 Maven 存储库。
repositories {
mavenCentral()
maven {
name 'Custom Maven Repository',
url 'http://repository-gradle-in-action.forge.cloudbees.com/release/')
}
}
我无法在本章中讨论每个可用的配置选项,因此请参阅在线文档以获取更多信息。 让我们看看 Ivy 存储库与 Maven 存储库及其配置有何不同。
Ivy 仓库
Maven 存储库中的工件必须以固定布局存储。 任何偏离该结构的行为都会导致无法解决的依赖关系。 另一方面,尽管 Ivy 存储库提出了默认布局,但它是完全可定制的。 在 Ivy 中,存储库依赖元数据存储在名为 ivy.xml 的文件中。 Gradle 提供了多种方法来配置 Ivy 存储库及其在构建中的特定布局。 涵盖所有选项超出了本书的范围,但让我们看一个例子。 想象一下,您想要从 Ivy 存储库中解析 Cargo 依赖项。 以下清单演示了如何定义存储库基本 URL,以及工件和元数据布局模式。
repositories {
ivy { // Ivy 存储库基本 URL
url 'http://repository.myenterprise.com/ivy/bundles/release'
layout 'pattern', {
// artifact模式
artifact '[organisation]/[module]/[revision]/[artifact]-[revision].[ext]'
// 元数据模式
ivy '[organisation]/[module]/[revision]/ivy-[revision].xml'
}
}
}
与 Maven 存储库中的 POM 一样,您不必被迫使用 Ivy 元数据来解决传递依赖项。 Ivy 存储库非常适合解决不一定遵循标准 Maven 工件模式的依赖关系。 例如,您可以决定将 JAR 文件放入 Web 服务器的特定目录中并通过 HTTP 提供服务。 为了完成关于存储库的讨论,我们将看看平面目录。
扁平目录存储库
存储库最简单和最基本的形式是平面目录存储库。 它是文件系统中的单个目录,仅包含 JAR 文件,没有元数据。 如果您习惯于使用项目源手动维护库并计划迁移到自动依赖项管理,那么您会对这种方法感兴趣。
声明依赖项时,只能使用属性名称和版本。 组属性不会被评估,如果您尝试使用它,则会导致未解决的依赖关系。 下一个清单展示了如何将 Cargo 依赖项声明为从平面目录存储库检索的映射和快捷方式符号。
repositories {
flatDir(dir: "${System.properties['user.home']}/libs/cargo", name: 'Local libs directory')
}
dependencies { // 依赖属性名称和版本的使用
cargo name: 'activation', version: '1.1'
cargo name: 'ant', version: '1.7.1'
cargo name: 'ant-launcher', version: '1.7.1'
cargo name: 'cargo-ant', version: '1.3.1'
cargo name: 'cargo-core-uberjar', version: '1.3.1'
cargo name: 'commons-discovery', version: '0.4'
cargo name: 'commons-logging', version: '1.0.4'
cargo name: 'dom4j', version: '1.4'
cargo name: 'isorelax', version: '20020414'
// 使用不带组属性的依赖快捷表示法
cargo ':jaxb-api:2.1', ':jaxb-impl:2.1.13', ':jaxen:1.0-FCS', ':jdom:1.0', ':msv:20020414', ':relaxngDatatype:20020414', ':saxpath:1.0-FCS', ':stax-api:1.0-2', ':xercesImpl:2.8.1', ':xml-apis:1.3.03'
}
此清单还完美地展示了能够使用自动声明传递依赖项的元数据有多么有用。 对于平面目录存储库,您没有此信息,因此您需要单独声明每个依赖项,这可能会变得非常累人。