掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
如果你使用過 Spring Boot,應(yīng)該能注意到我們只需要聲明使用的庫即可,而不必指定版本。如下所示:

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'javax.cache:cache-api'
implementation 'jakarta.xml.bind:jakarta.xml.bind-api'
runtimeOnly 'org.springframework.boot:spring-boot-starter-actuator'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
那么這是如何實(shí)現(xiàn)的呢?答案當(dāng)然是使用Bom進(jìn)行版本管理。
不使用Bom將會(huì)存在很多問題,如下:
舉一個(gè)例子,app項(xiàng)目引入guava:31.1版本,又引入了lib,lib中依賴了guava:25.0,這時(shí)候?qū)?huì)存在兩個(gè)版本,如果還依賴了其他lib,其中又依賴了其他的guava版本,那么項(xiàng)目中同一個(gè)依賴將存在非常多的版本,難以管理。且與其他項(xiàng)目組協(xié)作時(shí),版本不統(tǒng)一可能導(dǎo)致很多編譯錯(cuò)誤。
比如在guava:25.0中的這段代碼:
public class FutureStub {
public static Future ofString(String s) {
doSomethingFunOnPurpose();
return CompletableFuture.completedFuture(s);
}
private static void doSomethingFunOnPurpose() {
Futures.immediateCheckedFuture(new Object());
}
}
public class App {
public static void main(String[] args) throws Exception {
final var future = FutureStub.ofString("Hello Maven BOM");
System.out.println(future.get());
}
}
在App類中的main函數(shù)對(duì)FutureStub.ofString方法進(jìn)行調(diào)用,這段代碼在guava:25.0中運(yùn)行良好,但在當(dāng)前App項(xiàng)目中就會(huì)報(bào)錯(cuò),原因是該方法在guava:28后就已經(jīng)廢棄了。
那么要如何統(tǒng)一管理Bom呢?可以使用 Gradle 或者 Maven。
ext {
// 定義BOM版本
bomVersion = '1.0.0'
// 定義依賴項(xiàng)的版本號(hào)
dependencies = [
'dependency1': '1.2.3',
'dependency2': '4.5.6',
// 添加更多依賴項(xiàng)...
]
}
// 創(chuàng)建BOM配置
configurations {
bom
}
// 生成BOM文件
task generateBom {
outputs.file("dependencies.bom")
doLast {
def bomFile = new File(outputs.files.singleFile, "dependencies.bom")
bomFile.text = configurations.bom.getResolvedConfiguration().getFirstLevelModuleDependencies().collect { dep ->
"${dep.moduleGroup}:${dep.moduleName}:${dep.moduleVersion}"
}.join("\n")
}
}
apply from: 'dependencies.gradle'
plugins {
id 'maven-publish'
}
// 發(fā)布到Maven倉庫
publishing {
repositories {
maven {
url "https://your.maven.repository.url" // 替換為實(shí)際的Maven倉庫地址
credentials {
username 'your-username' // 替換為Maven倉庫的用戶名
password 'your-password' // 替換為Maven倉庫的密碼或API密鑰
}
}
}
publications {
mavenBom(MavenPublication) {
artifactId 'your-bom-artifact' // 替換為您的BOM的Artifact ID
version bomVersion
groupId 'your.group.id' // 替換為您的BOM的Group ID
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
dependencies.each { depName, depVersion ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', 'your.dependency.group.id') // 替換為實(shí)際的依賴項(xiàng)的Group ID
dependencyNode.appendNode('artifactId', depName)
dependencyNode.appendNode('version', depVersion)
}
}
}
}
}
// 發(fā)布任務(wù)
task publishToMavenRepository {
dependsOn generateBom
dependsOn publish
}
./gradlew publishToMavenRepository
這樣就完成了Bom的定義和發(fā)布,可以在Bom中統(tǒng)一管理項(xiàng)目中的依賴項(xiàng)版本,并可以讓其他團(tuán)隊(duì)使用這個(gè)Bom。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流