持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
前言
本系列目录
- Task
- Project、Task常用API
- 文件操作
- 依赖管理
- 多模块构建
- 插件编写
- SpringBoot插件源码分析
- 过度到Kotlin
在通过IDEA创建一个Gradle项目后,其他配置可以不需要改,但是你一定会多多少少使用第三方依赖,Gradle管理依赖比Maven更简单、简洁。
dependencies
Project提供的dependencies闭包函数用于管理依赖,通常我们在下面继续使用implementation等来引入第三方依赖,这个依赖,可以是本地模块、本地jar文件、远程仓库中jar。
dependencies {
configurationName dependencyNotation
}
上述中configurationName则可以是一个implementation,当然还有其他的,比如compileOnly,dependencyNotation则表示依赖的标识符.
configurationName是可以自定义的。
implementation
如下,是引入fastjson这个库,group和name就不说了,大家都懂是什么。
dependencies {
implementation group: 'com.alibaba', name: 'fastjson', version: '2.0.5'
}
但这样还是不行,因为我们还没告诉仓库地址,Gradle不知道从什么地方下载,所以我们还要通过repositories告诉其中一个仓库是maven中央仓库。
repositories {
mavenCentral()
}
这个仓库并不止这一个,还可以指定一个本地仓库,比如使用mavenLocal(),表示使用maven的本地仓库。
我们知道Gradle和Maven是两种不同的构建工具,它们都有自己的本地仓库,在使用mvn install
下载安装依赖时,Maven会把项目中引入的依赖下载到本地缓存起来,Gradle也是类似,他也会进行缓存,但是两种缓存的目录结构不一样,这就导致他们不通用,结果就是本地有两个用来缓存中央仓库依赖的目录,这显然很浪费空间,但我没想明白Gradle为什么要把缓存目录设计成这样,不能兼容Maven。
如果你想看他们的结构,可以去下面这个目录
Gradle:C:\Users\用户名.gradle\caches
Maven:C:\Users\用户名.m2\repository
但好在Gradle也提供了解决方案,就是使用mavenLocal(),mavenLocal()告诉Gradle先在本地Maven存储库中寻找依赖,如果不存在,则在尝试从远程获取它,但Gradle官方却建议避免添加mavenLocal()
,详细可查看官网,但人家也说了,比如项目A是用Maven构建的,项目B是用Gradle构建的,开发时需要共享依赖是,需要这种方式。
repositories{
mavenLocal ( )
mavenCentral ( )
}
还有个仓库是google提供的,用于提供Android依赖,包括 Android SDK,在Java后端开发中很少见,如果使用AndroidStudio创建的Android工程,那么必定会使用google这个仓库,哦对了,Android就是使用Gradle进行构建的。
同时还可以指定一个url路径作为仓库地址,如果我们自己搭建一个服务,可以使用这种方式。
repositories {
maven {
url "https://repo.spring.io/release"
}
}
dependencies {
implementation group: 'com.gopivotal.manager', name: 'session-managers', version: '1.2.1.RELEASE'
}
如上,这个仓库是spring提供的。
注意的是,声明的顺序也决定了Gradle会按照这个顺序下载依赖,并且如果Gradle在这个仓库中找到了对应的依赖,那么这个依赖所依赖的其他依赖,也会在这同一个仓库所下载。
files
但除了中央仓库的依赖,还有一部分依赖是我们自己开发的,不在中央仓库中,那么可以通过files指定本地的jar路径。
implementation files('hibernate.jar', 'libs/spring.jar'){ include '*.jar' }
也可以把某个路径下所有jar添加到项目中。
implementation fileTree('libs'){ include '*.jar' }
project
project用于在多模块的时候使用,比如web模块要依赖system模块,可以这样写。
implementation(project(":system"))
runtimeOnly
用他来表示只有运行时候才依赖,编译时不依赖,如下,这样引入后开发时并不能使用fastjson。
dependencies {
runtimeOnly group: 'com.alibaba', name: 'fastjson', version: '2.0.5'
}
那怎么变成运行时呢?这其实就是打包后通过java -jar
运行,首先安装java这个插件,这个插件可以打包出jar文件。
plugins {
id 'java'
}
但是对于有依赖的项目,还需要我们自己动一些手脚,如下,通过configurations.runtimeClasspath
获取运行时所依赖的jar文件,然后通过zipTree解压后复制到我们项目中,这样一个完整的项目就打包好了,可以直接执行java -jar
运行。
plugins {
id 'java'
}
jar{
manifest {
attributes( "Main-Class": "gradle.test.App")
}
from{
configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect {
zipTree(it)
}
}
}
repositories {
mavenCentral()
}
dependencies {
runtimeOnly group: 'com.alibaba', name: 'fastjson', version: '2.0.5'
}
compileOnly
如果把它换成compileOnly,则表示只有在编译时有效,打包时不包括。
dependencies {
compileOnly group: 'com.alibaba', name: 'fastjson', version: '2.0.5'
}
注意,implementation是两者,既在编译时存在,也在运行时存在,所以平常开发都会使用implementation,用runtimeOnly的情况可能是线上没有这个依赖,我们需要一起发布,而compileOnly则相反,我们只在本地使用他进行编译,线上环境有这个依赖了,所以我们不再发布。
其他类型
还有testCompileOnly、testRuntimeOnly、testImplementation也是类似,看名字大家都能猜到是干什么。
排除
如下,mysql驱动包还依赖protobuf-java这个包,可以使用exclude进行排除,这样在打包时,被排除的包也不会出现。
dependencies {
implementation( group: 'mysql', name: 'mysql-connector-java', version: '8.0.29'){
exclude group:"com.google.protobuf",module:"protobuf-java"
}
}
查看依赖树
如果想查看某个依赖的依赖树,可以执行下面命令。
gradlew -q [模块名]:dependencies
他会列出每个配置下的依赖树,如下,这样可以直观的显示出如mysql还依赖protobuf-java这个库。
annotationProcessor - Annotation processors and their dependencies for source set 'main'.
No dependencies
apiElements - API elements for main. (n)
No dependencies
.....
runtimeClasspath - Runtime classpath of source set 'main'.
\--- mysql:mysql-connector-java:8.0.29
\--- com.google.protobuf:protobuf-java:3.19.4
但也可以增加选项,只显示runtimeClasspath路径下的依赖。
./gradlew -q app:dependencies --configuration runtimeClasspath
上面说过,这个可以自定义,在以前的文章也演示了如何自定义,
configurations.create("myConfig")
repositories {
mavenCentral()
}
dependencies {
// implementation( group: 'mysql', name: 'mysql-connector-java', version: '8.0.29')
myConfig ( group: 'mysql', name: 'mysql-connector-java', version: '8.0.29')
}
这时候可以用下面命令来显示使用myConfig所依赖的库。
./gradlew -q app:dependencies --configuration myConfig
并且可通过下面任务获取所依赖的库的所有路径。
task list{
doLast {
configurations.myConfig.forEach{
println(it)
}
}
}