依赖元数据指的是与依赖相关联的信息,它描述了依赖的特征、关系和需求。

这些元数据包括以下详细信息:

  1. 标识:模块依赖通过它们的群组、名称和版本(GAV)坐标唯一标识。

  2. 依赖项:此依赖所需的其他二进制文件的列表,包括它们的版本。

  3. 变体:组件的不同形式(例如,编译、运行时、apiElements、runtimeElements),可以在不同的上下文中消费。

  4. 制品:组件实际生成的文件(如JARs、ZIPs等),可能包括编译后的代码、资源或文档。

  5. 能力:描述模块提供或消费的功能或特性,有助于避免当不同模块提供相同能力时发生冲突。

  6. 属性:用于区分变体的键值对(例如 org.gradle.jvm.version:8)。

根据仓库类型,依赖元数据以不同的格式存储:

  • Gradle: Gradle 模块元数据 (.module) 文件

  • Maven: Maven POM (pom.xml) 文件

  • Ivy: Ivy 描述符 (ivy.xml) 文件

某些仓库可能包含单个组件的多种元数据类型。当 Gradle 发布到 Maven 仓库时,它会同时发布 Gradle 模块元数据 (GMM) 文件和 Maven POM 文件。

这些元数据在依赖解析中扮演着关键角色,它允许二进制制品的依赖与制品本身一同被追踪。通过读取依赖元数据,Gradle 能够确定给定依赖项所需的其他制品的版本。

在 Maven 中,一个模块可以有**一个且只有一个制品**。在 Gradle 和 Ivy 中,一个模块可以有**多个制品**。

支持的元数据格式

外部模块依赖需要模块元数据,以便 Gradle 确定模块的传递依赖。Gradle 支持各种元数据格式来实现这一点。

Gradle 模块元数据 (GMM) 文件

Gradle 模块元数据是专门为支持 Gradle 依赖管理模型的所有功能而设计的,使其成为首选格式。

您可以在此处找到规范

{
  "formatVersion": "1.1",
  "component": {
    "group": "com.example",
    "module": "my-library",
    "version": "1.0"
  }
}

POM 文件

Gradle 原生支持Maven POM 文件。默认情况下,Gradle 会首先查找 POM 文件。但是,如果该文件包含特殊标记,Gradle 将改为使用Gradle 模块元数据

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>my-library</artifactId>
  <version>1.0</version>
</project>

Ivy 文件

Gradle 还支持Ivy 描述符文件。Gradle 会首先查找 ivy.xml 文件,但如果此文件包含特殊标记,它将改为使用Gradle 模块元数据

<ivy-module version="2.0">
  <info organisation="com.example" module="my-library" revision="1.0"/>
  <dependencies>
    <dependency org="org.example" name="dependency" rev="1.2"/>
  </dependencies>
</ivy-module>

支持的元数据来源

在仓库中搜索组件时,Gradle 默认检查支持的元数据文件格式

  • Gradle 首先查找 .module (Gradle 模块元数据) 文件。

  • 在 Maven 仓库中,Gradle 接着查找 .pom 文件。

  • 在 Ivy 仓库中,它检查 ivy.xml 文件。

  • 在扁平目录仓库中,它直接查找 .jar 文件,不期望任何元数据。

如果您定义自定义仓库,可以配置 Gradle 如何搜索元数据。例如,您可以设置一个 Maven 仓库,它将可选地解析没有关联 POM 文件的 JAR。这通过配置仓库的元数据来源来完成

build.gradle.kts
repositories {
    maven {
        url = uri("http://repo.mycompany.com/repo")
        metadataSources {
            mavenPom()
            artifact()
        }
    }
}
build.gradle
repositories {
    maven {
        url = "http://repo.mycompany.com/repo"
        metadataSources {
            mavenPom()
            artifact()
        }
    }
}

您可以指定多个元数据来源,Gradle 将以预定义的顺序搜索它们。支持以下元数据来源:

元数据来源 描述 默认顺序 Maven Ivy / 扁平目录

gradleMetadata()

查找 Gradle .module 文件

第1位

mavenPom()

查找 Maven .pom 文件

第2位

ivyDescriptor()

查找 ivy.xml 文件

第2位

artifact()

直接查找制品,不带关联元数据

第3位

默认情况下,Gradle 将要求依赖项具有关联的元数据。

要放宽此要求并允许 Gradle 解析不带关联元数据的制品,请指定 artifact 元数据来源:

mavenCentral {
    metadataSources {
        mavenPom()
        artifact()
    }
}

上述示例指示 Gradle 首先从 POM 文件中查找组件元数据,如果不存在,则从制品本身派生元数据。

例如,如果您声明一个模块依赖,Gradle 会在仓库中查找模块元数据文件(.module.pomivy.xml)。如果存在这样的模块元数据文件,它将被解析,并且该模块的制品(例如 hibernate-3.0.5.jar)及其依赖项(例如 cglib)将被下载。如果不存在这样的模块元数据文件,您需要配置元数据来源定义以直接查找名为 hibernate-3.0.5.jar 的制品文件

repositories {
    maven {
        url "https://repo.example.com/maven"
        metadataSources {
            mavenPom()   // Look for a POM file
            artifact()   // If no metadata is found, look for JARs directly
        }
    }
}

解析元数据文件(Ivy 或 Maven)时,Gradle 会检查是否存在一个标记,该标记指示存在匹配的 Gradle 模块元数据文件。如果找到,Gradle 将优先选择 Gradle 元数据。

要禁用此行为,请使用 ignoreGradleMetadataRedirection() 选项

build.gradle.kts
repositories {
    maven {
        url = uri("http://repo.mycompany.com/repo")
        metadataSources {
            mavenPom()
            artifact()
            ignoreGradleMetadataRedirection()
        }
    }
}
build.gradle
repositories {
    maven {
        url = "http://repo.mycompany.com/repo"
        metadataSources {
            mavenPom()
            artifact()
            ignoreGradleMetadataRedirection()
        }
    }
}