依赖管理的基础知识

  • 什么是依赖管理

  • 声明你的依赖

  • 依赖配置

  • 外部的依赖

  • 仓库

  • 发布 artifacts

什么是依赖管理?

粗略的讲, 依赖管理由两部分组成. 首先, Gradle 需要了解你的项目需要构建或运行的东西, 以便找到它们. 我们称这些传入的文件为项目的 dependencies(依赖项). 其次, Gradle 需要构建并上传你的项目产生的东西. 我们称这些传出的项目文件为 publications(发布项). 让我们来看看这两条的详细信息:

大多数项目都不是完全独立的. 它们需要其它项目进行编译或测试等等. 举个例子, 为了在项目中使用 Hibernate, 在编译的时候需要在 classpath 中添加一些 Hibernate 的 jar 路径. 要运行测试的时候, 需要在 test classpath 中包含一些额外的 jar, 比如特定的 JDBC 驱动或者 Ehcache jars.

这些传入的文件构成上述项目的依赖. Gradle 允许你告诉它项目的依赖关系, 以便找到这些依赖关系, 并在你的构建中维护它们. 依赖关系可能需要从远程的 Maven 或者 Ivy 仓库中下载, 也可能是在本地文件系统中, 或者是通过多项目构建另一个构建. 我们称这个过程为 dependency resolution(依赖解析).

这一特性与 Ant 相比效率提高了许多. 使用 Ant, 你只有指定 jar 的绝对路径或相对路径才能读取 jar. 使用 Gradle, 你只需要申明依赖的名称, 然后它会通过其它的设置来决定在哪里获取这些依赖关系, 比如从 Maven 库. 你可以为 Ant 添加 Apache Ivy 库或得类似的方法, 但是 Gradle 做的更好.

通常, 一个项目本身会具有依赖性. 举个例子, 运行 Hibernate 的核心需要其他几个类库在 classpath 中. 因此, Gradle 在为你的项目运行测试的时候, 它会找到这些依赖关系, 并使其可用. 我们称之为transitive dependencies(依赖传递).

大部分项目的主要目的是要建立一些文件, 在项目之外使用. 比如, 你的项目产生一个 Java 库,你需要构建一个jar, 可能是一个 jar 和一些文档, 并将它们发布在某处.

这些传出的文件构成了项目的发布. Gradle 当然会为你负责这个重要的工作. 你声明项目的发布, Gradle 会构建并发布在某处. 究竟什么是"发布"取决于你想做什么. 可能你希望将文件复制到本地目录, 或者将它们上传到一个远程 Maven 或者 Ivy 库.或者你可以使用这些文件在多项目构建中应用在其它的项目中. 我们称这个过程为 publication(发布)

声明你的依赖

让我们看一下一些依赖的声明. 下面是一个基础的构建脚本:

例子 8.1. 声明依赖

build.gradle

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

这里发生了什么? 这个构建脚本声明 Hibernate core 3.6.7.最终 被用来编译项目的源代码. 言外之意是, 在运行阶段同样也需要 Hibernate core 和它的依赖. 构建脚本同样声明了需要 junit >= 4.0 的版本来编译项目测试. 它告诉 Gradle 到 Maven 中央仓库里找任何需要的依赖. 接下来的部分会具体说明.

依赖配置

在 Gradle 里, 依赖可以组合成configurations(配置). 一个配置简单地说就是一系列的依赖. 我们称它们为(dependency configuration)依赖配置. 你可以使用它们声明项目的外部依赖. 正如我们将在后面看到, 它们也被用来声明项目的发布.

Java 插件定义了许多标准的配置. 下面列出了一些, 你也可以在Table 23.5, “Java 插件 - 依赖管理”里发现更多具体的信息.

compile

用来编译项目源代码的依赖.

runtime

在运行时被生成的类使用的依赖. 默认的, 也包含了编译时的依赖.

testCompile

编译测试代码的依赖. 默认的, 包含生成的类运行所需的依赖和编译源代码的依赖.

testRuntime

运行测试所需要的依赖. 默认的, 包含上面三个依赖.

各种各样的插件加入许多标准的配置. 你也可以定义你自己的配置. 参考 Section 52.3, “配置依赖”可以找到更加具体的定义和定制一个自己的依赖配置.

外部的依赖

你可以声明许多种依赖. 其中一种是external dependency(外部依赖). 这是一种在当前构建之外的一种依赖, 它被存放在远程或本地的仓库里, 比如 Maven 的库, 或者 Ivy 库, 甚至是一个本地的目录.

下面的例子讲展示如何加入外部依赖

例子 8.2. 定义一个外部依赖

build.gradle

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
}

引用一个外部依赖需要使用 group, name 和 version 属性. 根据你想要使用的库, group 和 version 可能会有所差别.

有一种简写形式, 只使用一串字符串 "group:name:version".

例子 8.3. 外部依赖的简写形式

build.gradle

dependencies {
    compile 'org.hibernate:hibernate-core:3.6.7.Final'
}

要了解跟多关于定义并使用依赖工作的信息,参见Section 52.4,"How to declare you dependencies".

仓库

Gradle 是怎样找到那些外部依赖的文件的呢? Gradle 会在一个repository(仓库)里找这些文件. 仓库其实就是文件的集合, 通过 group, nameversion 整理分类. Gradle 能解析好几种不同的仓库形式, 比如 Maven 和 Ivy, 同时可以理解各种进入仓库的方法, 比如使用本地文件系统或者 HTTP.

默认地, Gradle 不提前定义任何仓库. 在使用外部依赖之前, 你需要自己至少定义一个库. 比如使用下面例子中的 Maven central 仓库:

例子 8.4. Maven central 仓库

build.gradle

repositories {
    mavenCentral()
}

或者使用一个远程的 Maven 仓库:

例子 8.5. 使用远程的 Maven 仓库

build.gradle

repositories {
    maven {
        url "http://repo.mycompany.com/maven2"
    }
}

或者一个远程的 Ivy 仓库:

例子 8.6. 使用远程的 Ivy 仓库

build.gradle

repositories {
    ivy {
        url "http://repo.mycompany.com/repo"
    }
}

你也可以使用本地的文件系统里的库. Maven 和 Ivy 都支持下载的本地.

例子 8.7. 使用本地的 Ivy 目录

build.gradle

repositories {
    ivy {
        // URL can refer to a local directory
        url "../local-repo"
    }
}

一个项目可以有好几个库. Gradle 会根据依赖定义的顺序在各个库里寻找它们, 在第一个库里找到了就不会再在第二个库里找它了.

可以在Section 50.6 章, “仓库”里找到更详细的信息.

发布 artifacts

依赖配置也可以用来发布文件[3]. 我们称这些文件publication artifacts, 或者就叫 artifacts.

插件可以很好的定义一个项目的 artifacts, 所以你并不需要做一些特别的工作来让 Gradle 需要发布什么. 你可以通过在 uploadArchives 任务里加入仓库来完成. 下面是一个发布远程 Ivy 库的例子:

例子 8.8. 发布一个 Ivy 库

build.gradle

uploadArchives {
    repositories {
        ivy {
            credentials {
                username "username"
                password "pw"
            }
            url "http://repo.mycompany.com"
        }
    }
}

现在, 当你运 gradle uploadArchives, Gradle 将构建和上传你的 Jar. Gradle 也会生成和上传 ivy.xml .

你也可以发布到 Maven 库.语法是稍有不同[4]. 请注意你需要加入 Maven 插件来发布一个 Maven 库. 在下面的例子里, Gradle 将生成和上传 pom.xml.

例子 8.9. 发布 Maven 库

build.gradle

apply plugin: 'maven'

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file://localhost/tmp/myRepo/")
        }
    }
}

Chapter 53, Publishing artifacts, 发布 artifacts 里有更加具体的介绍.

[3] 我们认为这令人困惑,我们正在在Gradle DSL中逐步的区别这两个概念.

[4] 我们正在努力解决从Maven仓库发布,获取的语法一致性.