1. 引言
Spring Boot 是一個優秀的框架,可以快速啓動新的項目。它幫助開發者快速創建新應用程序的一種方式是定義一組適合大多數用户的依賴項。
然而,在某些情況下,可能需要覆蓋一個或多個依賴項的版本。
在本教程中,我們將探討如何覆蓋 Spring Boot 管理的依賴項及其版本。
2. Spring Boot 構件清單 (BOM)
讓我們先看看 Spring Boot 如何管理依賴項。簡而言之,Spring Boot 使用構件清單 (BOM) 來定義依賴項和版本。
大多數 Spring Boot 項目會繼承 spring-boot-starter-parent 構件,而該構件本身又會繼承 spring-boot-dependencies 構件。 該構件正是 Spring Boot BOM,它只是一個包含大量 dependencyManagement 節的部分 Maven POM 文件:
<dependencyManagement>
<dependencies>
<dependency>
...
</dependency>
<dependency>
...
</dependency>
</dependencies>
</dependencyManagement>通過使用 Maven 的 dependencyManagement 功能,BOM 可以指定默認的庫版本,如果我們的應用程序選擇使用它們。 讓我們來看一個例子。
一個 Spring Boot BOM 中的條目如下:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>${activemq.version}</version>
</dependency>這意味着項目中的任何依賴 ActiveMQ 的 Artifact 都會默認使用該版本。
此外,請注意 版本是通過屬性佔位符指定的。這在 Spring Boot BOM 中是一種常見的做法,它為自身 properties 部分提供該和其它屬性的值。
3. 覆蓋 Spring Boot 管理的依賴版本
現在我們已經瞭解了 Spring Boot 如何管理依賴版本,接下來我們將探討如何覆蓋這些版本。
3.1. Maven
對於 Maven,我們有以下兩種選項可以覆蓋 Spring Boot 管理的依賴項。首先,對於任何依賴項,如果 Spring Boot BOM 明確指定了帶有屬性佔位符的版本,我們只需在項目 POM 中設置該屬性即可:
<properties>
<activemq.version>5.16.3</activemq.version>
</properties>這會導致任何使用 activemq.version 屬性的依賴項使用我們指定的版本,而不是 Spring Boot BOM 中的版本。
此外,如果版本在 BOM 中的 dependency 標籤中明確指定,而不是作為佔位符,則我們只需在項目依賴項條目中明確覆蓋 version 即可。
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>5.16.3</version>
</dependency>3.2. Gradle
Gradle 需要一個插件來尊重 Spring Boot BOM 中的依賴管理。因此,為了開始,我們需要包含該插件並導入 BOM:
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:2.5.5'
}
}現在,如果我們想要覆蓋某個依賴項的特定版本,只需將相應的屬性作為 Gradle 的 ext 屬性指定即可:
ext['activemq.version'] = '5.16.3'如果 BOM 中不存在可覆蓋的屬性,我們始終可以在聲明依賴項時直接指定版本:
compile 'org.apache.activemq:activemq-amqp:5.16.3'3.3. 注意事項
以下幾點需要特別注意。
對於初學者來説,請記住 Spring Boot 的構建和測試依賴於其 BOM 中指定的庫版本。 任何時候我們指定不同的庫版本,都存在引入不兼容性的風險。 因此,在偏離標準依賴版本時,務必對我們的應用程序進行測試。
另外,請記住 這些建議僅適用於我們使用 Spring Boot Bill of Materials (BOM) 的情況。 對於 Maven,這意味着使用 Spring Boot 父模塊;對於 Gradle,則意味着使用 Spring 依賴插件。
4. 查找依賴版本
我們已經瞭解了 Spring Boot 如何管理依賴版本以及如何覆蓋它們。 在本節中,我們將探討如何查找項目正在使用的庫的版本。 這對於識別庫版本並確認我們對項目應用的任何覆蓋更改是否被尊重非常有用。
4.1. Maven
Maven 提供了一個目標,我們可以使用它來顯示所有依賴項及其版本列表。例如,如果運行以下命令:
mvn dependency:tree我們應該看到類似如下輸出:
[INFO] com.baeldung:dependency-demo:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.5.7-SNAPSHOT:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.5.7-SNAPSHOT:compile
[INFO] | | +- org.springframework.boot:spring-boot:jar:2.5.7-SNAPSHOT:compile
[INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.5.7-SNAPSHOT:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.5.7-SNAPSHOT:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.6:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.6:compile輸出顯示了所有項目依賴的 Artifact 和版本。 這些依賴項以樹狀結構呈現,便於識別每個 Artifact 如何被導入到項目中。
在上面的示例中,logback-classic 這是一個依賴於 spring-boot-starter-logging 庫的依賴項,而後者本身也是 spring-boot-starter 模塊的依賴項。因此,我們可以沿着樹向上導航,返回到我們的頂級項目。
4.2. Gradle
Gradle 提供了一個任務,可以生成類似的依賴樹。例如,如果我們運行以下命令:
gradle dependencies我們將會得到類似以下輸出:
我們將獲得類似以下輸出:
compileClasspath - Compile classpath for source set 'main'.
\--- org.springframework.boot:spring-boot-starter-web -> 1.3.8.RELEASE
+--- org.springframework.boot:spring-boot-starter:1.3.8.RELEASE
| +--- org.springframework.boot:spring-boot:1.3.8.RELEASE
| | +--- org.springframework:spring-core:4.2.8.RELEASE
| | \--- org.springframework:spring-context:4.2.8.RELEASE
| | +--- org.springframework:spring-aop:4.2.8.RELEASE類似於 Maven 的輸出,我們可以輕鬆地確定每個 Artifact 被引入項目的原因,以及使用的版本。
5. 結論
在本文中,我們學習了 Spring Boot 如何管理依賴版本。我們還看到了如何在 Maven 和 Gradle 中覆蓋這些依賴版本。最後,我們看到了如何在兩種項目類型中驗證依賴版本。