maven項目依賴另一個項目,maven 依賴版本管理— dependencyManagement

 2023-10-06 阅读 24 评论 0

摘要:在開發 spring boot 項目時,你是否遇到過,有些依賴即使不寫版本號也能下載到某一版本的依賴。 比如下面這個案例 案例 pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM

在開發 spring boot 項目時,你是否遇到過,有些依賴即使不寫版本號也能下載到某一版本的依賴。

比如下面這個案例

案例

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.9.RELEASE</version><relativePath/></parent><groupId>com.wqlm</groupId><artifactId>boot</artifactId><version>0.0.1-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

可以看到 <dependencies> 下配置了三個依賴項

  • spring-boot-starter-web
  • mysql-connector-java
  • mybatis-spring-boot-starter

maven項目依賴另一個項目。這個項目雖然引用了三個依賴,但只有 mybatis-spring-boot-starter 這個依賴是寫了版本號的,其余兩個沒寫。

我們知道導入一個依賴需要提供依賴的坐標 (groupId、artifactId、version)

既然 spring-boot-starter-web 和 mysql-connector-java 沒有提供 version,那么應該無法正確下載依賴才對。

但實際情況如圖

在這里插入圖片描述
spring-boot-starter-web 和 mysql-connector-java 都能找到對應的版本,這是為什么。

maven reimport,parent

不知道大家注意到沒,該 pom 是有 parent 的

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.9.RELEASE</version><relativePath/>
</parent>

也就是說該項目繼承自 spring-boot-starter-parent 項目。具體繼承了那些東西,我們點進去及可以看到了

如下圖 spring-boot-starter-parent 又繼承自 spring-boot-dependencies
在這里插入圖片描述
再點進去可以看到 spring-boot-dependencies 的pom文件如下

在這里插入圖片描述
可以看到 spring-boot-dependencies 沒有 parent, 說明它是頂級pom,其中 <properties> 內定義了很多版本號,mysql-connector-java 的版本號就在里面

maven dependency plugin?在這里插入圖片描述
是不是和上面看到的版本號一樣,都是8.0.17

spring-boot-dependencies.pom

下面是 spring-boot-dependencies-2.1.9.RELEASE.pom 中的部分內容

在這里插入圖片描述
注意以下三個組件

  • properties
  • dependencyManagement
  • pluginManagement

其中 properties 定義了一系列的版本號,并且在 dependencyManagement 中使用了版本號。注意這個 dependencyManagement,它的下級是我們最常用的 dependencies 組件

maven版本管理,我們知道 dependencies 組件是用來引入依賴的,那在外面包上一層 dependencyManagement 是什么意思呢?它的意思是,聲明 dependencies 中的依賴,但不引用!!!那什么時候引用呢?當子項目中配置了一個 dependency ,并且這個 dependency沒寫版本號,且在 dependencyManagement 中聲明過時才引用。

這就是為什么有的依賴包需要寫版本號,有的不需要寫。那些不需要寫版本號的依賴,其實在它的父pom的dependencyManagement中已經申明好了,而且不僅申明了 version,有的還申明了 exclusions ,用于剔除某些沖突的依賴

pluginManagement

上面說了 dependencyplugin 也是同理。不信你回頭看案例的pom文件,它里面就定義了一個 spring-boot-maven-plugin 的插件,也沒有寫版本號。

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

它的版本號同樣是在父pom的 pluginManagement 中申明好的

dependencies 組件

dependencies 組件用于導入依賴,且所有 dependencies 里的依賴都會被子項目繼承。

公共依賴版本管理

maven依賴包?像 spring boot 這種大體量的框架,旗下子項目眾多,比如

  • spring-boot-starter-web
  • spring-boot-starter-amqp
  • spring-boot-starter-data-redis

  • 這些子項目也有各自的依賴,其中有些依賴是公共的,比如

spring-boot-starter-web-2.1.9.RELEASE 和 spring-boot-starter-data-redis–2.1.9.RELEASE 的依賴結構如下

他們都依賴了 spring-boot-starter,既然都是 spring-boot 的子項目,并且版本號也一樣,那么他們兩個依賴的 spring-boot-starter 的版本也應該要一樣,不然同時引用他們兩個就會出現依賴沖突!

如何保證所有子項目的公共依賴的版本一致呢,總不能在每個子項目里寫死吧,這樣手動去管理得累死。

所以 spring boot 將所有公共依賴抽離出來,放到 spring-boot-dependencies 中來管理。 所有的子項目都直接或間接繼承自 spring-boot-dependencies,這樣同一個版本的所有的子項目的公共依賴就都一樣了。

maven依賴范圍?但這樣做帶來了一個問題,每個子項目都繼承了所有的公共依賴,解決這件事情,就需要使用 maven 的 dependencyManagement 組件

dependencyManagement 組件

作用:用來申明依賴,但不導入。

dependencies 組件用于導入依賴,注意兩者區別

特性

  • 子項目不會繼承 dependencyManagement 組件中聲明的依賴。
  • 但如果子項目想導入某個父pom 中 dependencyManagement 中的依賴,只需要填寫 groupId 和 artifactId ,不需要填寫版本號,maven會自動去父pom 的 dependencyManagement 中找對應的 version,包括scope、exclusions等

使用 dependencyManagement 組件后,所有的子項目只需要在父pom 的 “公共依賴聲明池” 中挑選自己想要的依賴,而不用關心版本。這樣即不會繼承到不需要的依賴,又統一了依賴的版本

maven依賴管理。如果想統一調整所有子項目某個依賴的版本,只需要在父pom 里更新。不需要修改任何一個子項目。

如果某個子項目不想使用公共的版本號,只需要在 dependency 中加上版本號,子項目就會使用自定義的版本號,不會繼承父類版本號。

spring boot 就是通過這樣來統一管理依賴版本的

基于這樣的特性, dependencyManagement 組件 一般用于統一管理子項目的公共依賴的版本

依賴版本的查找

maven傳遞依賴。Maven會沿著父子層次向上走,直到找到一個擁有 dependencyManagement 組件的項目,然后在其中查找,如果找到則返回申明的依賴,沒有繼續往下找。

dependencies 與 dependencyManagement 的區別

dependencies

  • 引入依賴
  • 即使子項目中不寫 dependencies ,子項目仍然會從父項目中繼承 dependencies 中的所有依賴項

dependencyManagement

  • 聲明依賴,并不引入依賴。
  • 子項目默認不會繼承父項目 dependencyManagement 中的依賴
  • 只有在子項目中寫了該依賴項,并且沒有指定具體版本,才會從父項目中繼承(version、exclusions、scope等讀取自父pom)
  • 子項目如果指定了依賴的具體版本號,會優先使用子項目中指定版本,不會繼承父pom中申明的依賴

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/120978.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息