Gradle依赖管理

依赖管理是每一个构建工具最为关键的特性。

下面是Gradle依赖管理所支持的特性:

  • 支持传递依赖管理
  • 支持对非仓库依赖的管理:依赖只是简单的文件
  • 支持自定义依赖配置
  • 完全可以自定义的依赖解析策略
  • 完全兼容Maven和Ivy
  • 与现有依赖管理基础架构集成:如果你使用Archiva,Nexus或者Artifactory,Gradle是100%完全兼容所有仓库格式

从Ant轻松的迁移依赖

项目的迁移通常都是逐步,任何一个大型的项目,不可能一步到位。

Gradle支持非仓库的文件依赖管理,所以如果你的遗留项目是基于Ant,且依赖文件是通过文件夹管理(比如:lib),使用Gradle的依赖管理,可以无缝的迁移过来。

Gradle还支持将一个项目作为依赖,如果你项目是由多个子项目组成,并且相互直接存在依赖关系,Gradle也可以非常轻松的驾驭。

依赖管理最佳实践

给Jar文件添加版本 虽然一个Jar文件的版本是通过Manifest文件来管理,但是这种方式实际上并不够一目了然。如果一口气给你20个Jar文件,你是希望每个文件都是commons-beanutils-1.3.jar这样的呢?还是像这样spring.jar?很明显是前者。

管理传递依赖 所谓传递依赖,就是项目所以依赖的Jar文件(或者其他文件),由(传递)依赖于另一个Jar文件(或者其他文件)。这种递归式的依赖策略,就会定义出一个以项目为起点的依赖层级树(tree of dependencies)。如果没有这样一个模型化的层级管理,依赖关系的管理很快就回失去控制。像一些使用了Spring,Hibernate或者其他库的大型项目,或者它包含成百上千个子内部项目,它就会拥有非常复杂的依赖树。

像这样的项目,通常改变一个或者若干个依赖的版本,就有可能导致某些依赖版本的冲突。人为的管理复杂依赖关系,最终导致的结果就是,没有人敢去修改依赖关系,因为风险太大。

解决版本冲突 同一个Jar文件的版本冲突,要么可以被解决,要么就回导致构建或者运行异常(例如:缺少某个方法),又或者表面运行正常,但实际引入了很多不安全Bug。

Gradle提供了优秀的依赖冲突报告工具,可以非常轻松的将报告结果共享。

Gradle提供了下面两种依赖冲突解决策略:

  • 使用最新版本:永远使用最新的那个版本。这是Gradle的默认策略,只要新的版本是向下兼容的,这就是最合适的策略。
  • 失败策略:只要版本冲突,就让构建失败。这个需要所有的版本冲突需要构建脚本中显示的解决。

上面两个策略,就已经足够解决大部分的版本冲突。但是,Gradle还提供了force关键字来进一步解决版本冲突。

使用动态版 在许多场景下,你希望使用某个依赖的最新版本,或者某个范围内的最新版本,这可能是开发过程中的一个需求。

比如:

compile 'com.android.support:appcompat-v7:23.0.+'

或者使用latest.integration来指定使用最新的版本。

configurations关键字 Gradle的依赖被分组成不同的configuration。configuration有自己的名字和其他属性,并且可以互相继承。Java插件提供了四个configuration,分别是compile,runtime,providedCompile,providedRuntime。 你也可以自己定义一个

configurations {
    database
}

dependencies {
    database 'mysql:mysql-connector-java:5.1.18'
}

println configurations.database.name
println configurations['database'].name

依赖定义的类型

类型 描述
外部模块依赖 仓库中依赖的使用
项目依赖 同一个构建中对另一个项目的依赖
文件依赖 本地文件系统中文件的依赖
客户端模块依赖 允许你直接在构建脚本中声明传递依赖,替代说明外部仓库中模块描述
Gradle API依赖 当前Gradle版本的API,一般在开发自定义的Gradle插件和任务时,才会使用该依赖
本地Groovy依赖 当前Gradle版本的Groovy,同样在开发Gradle插件和任务时才使用

外部模块依赖

dependencies {
    runtime group: 'org.springframework', name: 'spring-core', version: '2.5'
    runtime 'org.springframework:spring-core:2.5',
            'org.springframework:spring-aop:2.5'
    runtime(
        [group: 'org.springframework', name: 'spring-core', version: '2.5'],
        [group: 'org.springframework', name: 'spring-aop', version: '2.5']
    )
    runtime('org.hibernate:hibernate:3.0.5') {
        transitive = true
    }
    runtime group: 'org.hibernate', name: 'hibernate', version: '3.0.5', transitive: true
    runtime(group: 'org.hibernate', name: 'hibernate', version: '3.0.5') {
        transitive = true
    }
}

只下载Jar文件的注解

如果一个模块没有描述器,那么Gradle默认会下载满足该模块名字的Jar文件。有时候,模块中包含描述器,但是仍然想要只下载Jar文件,而不包含其对应的(传递)依赖文件。Gradle提供了artifact only的注解@,如下:

dependencies {
    runtime "org.groovy:groovy:2.2.0@jar"
    runtime group: 'org.groovy', name: 'groovy', version: '2.2.0', ext: 'jar'
}

客户端模块依赖

正如上面所介绍的,允许你直接在构建脚本中声明传递依赖,替代说明外部仓库中模块描述

dependencies {
    runtime module("org.codehaus.groovy:groovy:2.4.4") {
        dependency("commons-cli:commons-cli:1.0") {
            transitive = false
        }
        module(group: 'org.apache.ant', name: 'ant', version: '1.9.6') {
            dependencies "org.apache.ant:ant-launcher:1.9.6@jar",
                         "org.apache.ant:ant-junit:1.9.6"
        }
    }
}

项目依赖

多项目构建过程中,常常出现的一个场景,就是一个项目模块,依赖于另一个共享的或者独立的项目模块。

dependencies {
    compile project(':shared')
}

文件依赖

遗留项目迁移时,最常使用的依赖配置。

dependencies {
    runtime files('libs/a.jar', 'libs/b.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
}

排除传递依赖

configurations {
    compile.exclude module: 'commons'
    all*.exclude group: 'org.gradle.test.excludes', module: 'reports'
}

dependencies {
    compile("org.gradle.test.excludes:api:1.0") {
        exclude module: 'shared'
    }
}
apply plugin: 'java' //so that I can declare 'compile' dependencies

 dependencies {
   compile('org.hibernate:hibernate:3.1') {
     //excluding a particular transitive dependency:
     exclude module: 'cglib' //by artifact name
     exclude group: 'org.jmock' //by group
     exclude group: 'org.unwanted', module: 'iAmBuggy' //by both name and group
   }
 }

依赖管理报告

gradle -q dependencies > dependencies.txt

results matching ""

    No results matching ""