粗略的讲, 依赖管理由两部分组成:项目的 dependencies(依赖项) 和 publications(发布项)。
简言为个人理解,细说为出处。若对简言不清楚,可查看理解细说部分。
大多数项目都不是完全独立的 ,它们需要其它项目进行编译或测试等等 。举个例子, 为了在项目中使用 Hibernate, 在编译的时候需要在 classpath 中添加一些 Hibernate 的 jar 路径. 要运行测试的时候, 需要在 test classpath 中包含一些额外的 jar, 比如特定的 JDBC 驱动或者 Ehcache jars.
这些传入的文件构成上述项目的依赖。 Gradle 允许你告诉它项目的依赖关系, 以便找到这些依赖关系, 并在你的构建中维护它们。
依赖关系可能需要从远程的 Maven 或者 Ivy 仓库中下载, 也可能是在本地文件系统中, 或者是通过多项目构建另一个构建。我们称这个过程为dependency resolution(依赖解析) 。
通常, 一个项目本身会具有依赖性. 举个例子, 运行 Hibernate 的核心需要其他几个类库在 classpath 中. 因此, Gradle 在为你的项目运行测试的时候, 它会找到这些依赖关系, 并使其可用 。 我们称之为transitive dependencies(依赖传递) 。
项目的主要目的是要建立一些文件,在项目之外使用。Gradle可以负责完成这一系列任务,而这一过程称为publication(发布)。
大部分项目的主要目的是要建立一些文件,在项目之外使用。比如,你的项目产生一个 Java 库,你需要构建一个jar,可能是一个 jar 和一些文档, 并将它们发布在某处。
这些传出的文件构成了项目的发布。Gradle 当然会为你负责这个重要的工作。你声明项目的发布,Gradle 会构建并发布在某处。究竟什么是"发布"取决于你想做什么。可能你希望将文件复制到本地目录, 或者将它们上传到一个远程 Maven 或者 Ivy 库.或者你可以使用这些文件在多项目构建中应用在其它的项目中。我们称这个过程为 publication(发布)。
简单的依赖声明:
//应用插件,这里引入了Gradle的Java插件,此插件提供了Java构建和测试所需的一切。
apply plugin: 'java'
//仓库:指明要从哪个仓库下载jar包
repositories {
mavenCentral()
}
//定义依赖:声明项目中需要哪些依赖
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
在 Gradle 里, 依赖可以组合成configurations(配置).。一个Configuration(配置)简单地说就是一系列的依赖。我们称它们为(dependency configuration)依赖配置。 你可以使用它们声明项目的外部依赖。正如我们将在后面看到,它们也被用来声明项目的发布。
Java插件定义了一些标准配置,形成了插件本身的类路径库。下面列一下,你可以自己去这看:Table 23.5, “Java plugin - dependency configurations”.
configuration | 含义 |
---|---|
compile | 用来编译项目源代码的依赖. |
runtime | 在运行时被生成的类使用的依赖. 默认的, 也包含了编译时的依赖. |
testCompile | 编译测试代码的依赖. 默认的, 包含生成的类运行所需的依赖和编译源代码的依赖. |
testRuntime | 运行测试所需要的依赖. 默认的, 包含上面三个依赖. |
简单实例:
dependencies {
compile module(":compile:1.0") {
dependency ":compile-transitive-1.0@jar"
dependency ":providedCompile-transitive:1.0@jar"
}
providedCompile "javax.servlet:servlet-api:2.5"
providedCompile module(":providedCompile:1.0") {
dependency ":providedCompile-transitive:1.0@jar"
}
compile `org.springframework:spring-web:4.3.4.RELEASE`
runtime ":runtime:1.0"
providedRuntime ":providedRuntime:1.0@jar"
testCompile 'junit:junit:4.11'
}
如上面中,一个compile即是一个Configuration,一个providedCompile也即是一个Configuration。
做web开发时需要servlet的依赖,但是只是编译阶段,运行时servlet依赖由servlet容器来提供。
所以Gradle的War插件也提供了两个configuration,分别是providedCompile和providedRuntime,它们对依赖的使用范围定义和compile以及runtime一致,只不过依赖的Jar包不会被加到War包里面 。
如上面示例中的
providedCompile "javax.servlet:servlet-api:2.5"
providedRuntime ":providedRuntime:1.0@jar"
传递依赖特性可以轻松地通过transitive参数进行开启或关闭,上面的示例中如果要忽略spring-web的传递性依赖可以采用指定 transitive = false 的方式来关闭依赖传递特性,也可以采用添加@jar的方式忽略该依赖的所有传递性依赖。
compile("org.springframework:spring-web:4.3.4.RELEASE") {
transitive = false
}
下面的语句,则可以全局性的关闭依赖传递特性。
configurations.all {
transitive = false
}
可能需要排除一些传递性依赖中的某个模块,这时需要exclude.
如果说@jar彻底的解决了传递问题,那么exclude则是部分解决了传递问题。
此外,exclude还可用于但不限于以下几种情况:
可以通过configuration配置或者在依赖声明时添加exclude的方式来排除指定的引用。
exclude可以接收group和module两个参数,这两个参数可以单独使用也可以搭配使用。
其中module可以理解为对应GAV中的artifactId,也就是compile group: 'org.gradle.test.classifiers', name: 'service', version: '1.0'中的中间name部分。
// 方法1. 直接在configuration中排除
configurations {
//编译期排除commons模块
compile.exclude module: 'commons'
//在整个构建过程中排除pkaq.tiger:share
all*.exclude group: 'pkaq.tiger', module: 'share'
}
// 方法2. 在具体的某个dependency中排除
dependencies {
compile("pkaq.tiger:web:1.0") {
exclude module: 'share'
}
}
有时可能会看到项目中有如下的配置:
configurations {
providedRuntime
}
该配置应该就是对模块/项目做的全局配置,设置依赖配置为“providedRuntime”。
如,为了构建一个即能执行也可以部署到外部容器的war包,你需要将内嵌容器依赖标记为”providedRuntime”,此时需要添加该字段。
apply plugin: 'war'
war {
baseName = 'myapp'
version = '0.5.0'
}
repositories {
jcenter()
maven { url "http://repo.spring.io/libs-snapshot" }
}
configurations {
providedRuntime
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
...
}