Gradle 提供 API 来声明仓库可能包含或不包含的内容。它有不同的使用场景

  • 性能 当你知道某个依赖永远不会在特定仓库中找到时

  • 安全性 通过避免泄露私有项目使用的依赖信息

  • 可靠性 当某些仓库包含无效或不正确的元数据或 Artifact 时

当考虑到仓库的声明顺序也很重要时,这一点尤为重要。

声明仓库过滤器

build.gradle.kts
repositories {
    maven {
        url = uri("https://repo.mycompany.com/maven2")
        content {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup("my.company")
        }
    }
    mavenCentral {
        content {
            // this repository contains everything BUT artifacts with group starting with "my.company"
            excludeGroupByRegex("my\\.company.*")
        }
    }
}
build.gradle
repositories {
    maven {
        url = "https://repo.mycompany.com/maven2"
        content {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup "my.company"
        }
    }
    mavenCentral {
        content {
            // this repository contains everything BUT artifacts with group starting with "my.company"
            excludeGroupByRegex "my\\.company.*"
        }
    }
}

默认情况下,仓库包含所有内容且不排除任何内容

  • 如果你声明了 include,则会排除所有内容,除了包含的内容。

  • 如果你声明了 exclude,则会包含所有内容,除了排除的内容。

  • 如果你同时声明了 includes 和 excludes,则只包含明确包含且未排除的内容。

可以通过显式的 groupmoduleversion 进行过滤,可以是严格匹配或使用正则表达式。使用严格版本时,可以使用版本范围,格式与 Gradle 支持的格式相同。此外,还可以根据解析上下文进行过滤:配置名称甚至配置属性。详见 RepositoryContentDescriptor

声明仅在单个仓库中找到的内容

使用 仓库级内容过滤器 声明的过滤器不是排他性的。这意味着声明一个仓库包含某个 Artifact,并不意味着其他仓库不能拥有它:你必须在扩展中声明每个仓库包含的内容。

或者,Gradle 提供了一个 API,允许你声明某个仓库独占性地包含某个 Artifact。如果你这样做

  • 在一个仓库中声明的 Artifact 不能在任何其他仓库中找到

  • 独占性仓库内容必须在扩展中声明(就像 仓库级内容 一样)

build.gradle.kts
repositories {
    // This repository will _not_ be searched for artifacts in my.company
    // despite being declared first
    mavenCentral()
    exclusiveContent {
        forRepository {
            maven {
                url = uri("https://repo.mycompany.com/maven2")
            }
        }
        filter {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup("my.company")
        }
    }
}
build.gradle
repositories {
    // This repository will _not_ be searched for artifacts in my.company
    // despite being declared first
    mavenCentral()
    exclusiveContent {
        forRepository {
            maven {
                url = "https://repo.mycompany.com/maven2"
            }
        }
        filter {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup "my.company"
        }
    }
}

可以通过显式的 groupmoduleversion 进行过滤,可以是严格匹配或使用正则表达式。详见 InclusiveRepositoryContentDescriptor

如果你在 settings.gradle(.kts) 文件的 pluginManagement 部分利用独占内容过滤,那么通过项目 buildscript.repositories 添加更多仓库将是非法的。在这种情况下,构建配置将失败。

你的选择要么是在 settings 文件中声明所有仓库,要么是使用非独占内容过滤。

Maven 仓库过滤

对于 Maven 仓库,通常一个仓库会包含发布版或快照版。Gradle 允许你使用这个 DSL 声明仓库中包含哪些类型的 Artifact

build.gradle.kts
repositories {
    maven {
        url = uri("https://repo.mycompany.com/releases")
        mavenContent {
            releasesOnly()
        }
    }
    maven {
        url = uri("https://repo.mycompany.com/snapshots")
        mavenContent {
            snapshotsOnly()
        }
    }
}
build.gradle
repositories {
    maven {
        url = "https://repo.mycompany.com/releases"
        mavenContent {
            releasesOnly()
        }
    }
    maven {
        url = "https://repo.mycompany.com/snapshots"
        mavenContent {
            snapshotsOnly()
        }
    }
}

启用 Ivy 动态解析模式

通常,在 Ivy 仓库中,依赖通过 ivy.xml 中的 rev (版本) 属性指定。然而,动态解析模式允许 Gradle 优先使用 revConstraint 属性而不是 rev

  • 如果 ivy.xml 中存在 revConstraint,Gradle 将使用它而不是 rev

  • 如果 revConstraint 不存在,Gradle 将回退到 rev

这为依赖解析提供了更大的灵活性,特别是在使用对可接受版本定义约束的 Ivy 仓库时。

声明 Ivy 仓库时,需要显式启用动态解析模式

build.gradle.kts
// Can enable dynamic resolve mode when you define the repository
repositories {
    ivy {
        url = uri("http://repo.mycompany.com/repo")
        resolve.isDynamicMode = true
    }
}

// Can use a rule instead to enable (or disable) dynamic resolve mode for all repositories
repositories.withType<IvyArtifactRepository> {
    resolve.isDynamicMode = true
}
build.gradle
// Can enable dynamic resolve mode when you define the repository
repositories {
    ivy {
        url = "http://repo.mycompany.com/repo"
        resolve.dynamicMode = true
    }
}

// Can use a rule instead to enable (or disable) dynamic resolve mode for all repositories
repositories.withType(IvyArtifactRepository) {
    resolve.dynamicMode = true
}
动态解析模式仅适用于 Gradle 的 Ivy 仓库。它不适用于 Maven 仓库或自定义 Ivy DependencyResolver 实现。