使用Version Catalog在项目之间共享版本
在进行Spring Boot进行微服务开发,或者有很多个应用时,不同的项目之间可能会因为使用Spring Boot的版本不同而造成彼此时间的不兼容。这个时候就可以通过统一项目的依赖版本来避免这个问题。本文将介绍使用Gradle的Version Catalog来统一项目版本的方法。
关于Version Catalog
Version Catalog是Gradle 7.0+引入的一个新特性(在7.4版本稳定),旨在简化和几种管理项目中的依赖版本。它允许开发人员在一个单独的文件或者项目中定义依赖的版本,这样做可以:
- 集中管理:将依赖和版本作为单独的项目,可以单独进行版本管理,便于维护和更新。
- 避免版本冲突:通过统一的版本管理,减少不同模块间因为引入依赖的不同版本而冲突。
在多个项目间共享版本
将Version Catalog作为一个单独的项目可以实现版本号和项目的解耦,这个项目也可以单独进行升级。
创建Gradle项目
这一步比较简单,创建一个空项目即可。为了后文方便阅读,我们为这个项目设置一些基础信息:
- Group Id:com.aquarius
- Artifact Id:aquarius-dependency-management
- 配置文件语言选择Kotlin风格,使用Groovy的读者可以参考后面的代码自行编写
- 版本号是1.0.0
添加Version Catalog插件
打开项目的build.gradle.kts
文件,添加插件:
plugins {`version-catalog`
}
定义版本清单
预定义版本号(可选)
如果有多个依赖有相同的版本,比如Kotlin的各种插件,那么就可以将版本号统一声明,便于后面使用,代码如下:
catalog {versionCatalog {version("kotlin", "2.0.20") // 当然也可以把"kotlin"单独定义一个变量,方便使用version("spring-boot", "3.3.3")}
}
定义版本清单
catalog {versionCatalog {// 前面定义的版本plugin("kotlin-jvm", "org.jetbrains.kotlin.jvm").version("2.0.20")plugin("kotlin-spring", "org.jetbrains.kotlin.plugin.spring").versionRef("kotlin") // 这里引用名为"kotlin"的版本号,即"2.0.20"// 定义库时可以像上面一样使用version函数,或者像下面一样直接写在依赖中library("kotlin-logging", "io.github.oshai:kotlin-logging-jvm:7.0.0")}
}
依赖命名规则和类型安全的访问器
依赖命名规则
在前面定义版本清单的时候,我们声明的kotlin-jvm
、kotlin-spring
和kotlin-logging
等都是对应依赖的别名,可以用来在其他项目中生成安全的访问器。依赖别名是由一系列以横线“-”(推荐方法)、下划线“_”或者点“.”分隔的标识符组成。标识符可以是ASCII字符(推荐使用小写字母),后面可以添加数字。下面列举一部分标识符规则(引用自Gradle官网):
guava
是一个合法的依赖别名groovy-core
是一个合法的依赖别名commons-lang3
是一个合法的别名androidx.awesome.lib
是合法的别名this.#is.not!
不是合法的别名
类型安全的访问器
假设其他项目在使用这个版本清单的时候定义的名称是libs
,那么对于下面的别名,将会生成对应的访问器(引用自Gradle官网):
guava
对应libs.guava
groovy-core
对应libs.groovy.core
groovy-xml
对应libs.groovy.xml
groovy-json
对应libs.groovy.json
androidx.awesome.lib
对应libs.androidx.awesome.lib
当然,如果想要避免上面的分组,可以使用大写字母来避免分割:groovyCore
对应libs.groovyCore
groovyXml
对应libs.groovyXml
groovyJson
对应libs.groovyJson
保留字和特殊命名
extensions
、class
和convention
是保留字,禁止用于定义版本清单的别名。bundles
、versions
和plugins
不能用于访问器的第一个分组,即versions-dependency
不被允许,但是versionDependency
或者dependency-version
是合法的别名。
将版本清单发布到代码仓库中
在前面我们已经定义了版本清单的内容,接下来将代码发布到仓库中,便于其他项目使用,这里我们打开build.gradle.kts
文件,所有的操作都在这里进行:
引入插件
// 添加Maven Publish插件
plugins {// ...`maven-publish`
}
配置发布内容
publishing {publications {create<MavenPublication>("maven") {from(components["versionCatalog"])}}
}
重新加载Gradle项目,此时会在项目中看见一系列新的Gradle任务:
![[新增的Gradle任务.png]]
此时可以双击publishToMavenLocal发布到本地仓库,也可以使用其他的发布方法,具体使用可以参考Gradle官网的文档。
对依赖进行版本管理(可选)
为了进一步管理依赖的版本,我们可以使用Gradle Release插件来对依赖进行版本管理。Gradle Release插件基于代码提交记录,支持Git、SVN、Mercurial和Bazaar。首先引入依赖:
plugins { id("net.researchgate.release") version "3.0.2"
}
重新加载Gradle项目,这时会出现相关的任务,我们点击release
即可:
![[Gradle Release的任务列表.png]]
如果使用Git管理项目的话,需要将当前分支命名为main,而不是master。此时就会在命令行进行以下操作:
- 检查所有未提交的代码,包括添加、修改、删除以及未被管理的代码。
- 检查代码变动。
- 签出到发布分支,并合并当前分支(只有Git有,且需要配置
pushReleaseVersionBranch
)。 - 移除项目版本号的SNAPSHOT(如果有的话)。
- 提示用户输入当前版本号,这一步需要用户输入。
- 检查项目使用使用SNAPSHOT版本号。
- 构建项目(执行
build
命令)。 - 提交项目代码(如果使用SNAPSHOT版本号)。
- 为当前版本添加Tag。
- 签出到当前工作分支(条件同第三步)。
- 提示用户输入下个版本号(用于下一次发布时第5部的默认值),这一步需要用户输入。
- 使用新的版本号提交项目代码。
之后就可以对Dependency Management项目进行版本管理,方便升级项目中的公共依赖。
在其他项目中使用版本清单
创建另一个项目,在settings.gradle.kts
文件中声明使用的版本清单:
dependencyResolutionManagement {// 其实也可以在这里声明项目的全局代码仓库,但是这个API并不稳定versionCatalogs { create("libs") {from("com.aquarius:aquarius-dependency-management:1.0.0") } }
}
这里的libs
就是我们为Version Catalog起的别名,在构建项目后,会自动生成一个libs
变量,我们就可以直接使用这个变量来声明依赖,无需手动指定版本。
在项目的build.gradle.kts
文件中,我们可以使用libs
提供的各种预定义的依赖项:
plugins {// 定义插件时需要使用alias定义alias(libs.kotlin.jvm)alias(libs.kotlin.spring)
}dependencies {// 定义依赖时可以和不使用Version Catalog时一样implementation(libs.kotlin.logging)
}
注意事项
Gradle依赖的Type和Classifier
在使用某些依赖时,我们会用到它的不同的变体(Variant),比如使用Spring Data Jpa和Querydsl时,如果使用Spring Boot 3,那么需要引用classifier为jakarta
的变体。这种行为无法在定义Version Catalog时进行,只能等到声明依赖的时候才能实现,详见参考链接中的GitHub Issue,下面给出合适的代码:
dependencies {kapt(libs.querydsl.jpa) {classifier = "jakarta"// 当然,也可以定义诸如type = "aar"等其他内容}
}
参考链接
这篇博客的编写主要参考Gradle官网的文档,以及一篇介绍Version Catalog的博客,其中关于Classifier的部分参考自GitHub的Issue:
- Gradle官网的文档
- 介绍Version Catalog的博客。
- GitHub的Issue