在開發 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>
下配置了三個依賴項
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 中使用了版本號。注意這個 dependencyManagement,它的下級是我們最常用的 dependencies 組件
maven版本管理,我們知道 dependencies 組件是用來引入依賴的,那在外面包上一層 dependencyManagement 是什么意思呢?它的意思是,聲明 dependencies 中的依賴,但不引用!!!那什么時候引用呢?當子項目中配置了一個 dependency ,并且這個 dependency沒寫版本號,且在 dependencyManagement 中聲明過時才引用。
這就是為什么有的依賴包需要寫版本號,有的不需要寫。那些不需要寫版本號的依賴,其實在它的父pom的dependencyManagement中已經申明好了,而且不僅申明了 version,有的還申明了 exclusions ,用于剔除某些沖突的依賴
上面說了 dependency,plugin 也是同理。不信你回頭看案例的pom文件,它里面就定義了一個 spring-boot-maven-plugin 的插件,也沒有寫版本號。
<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
它的版本號同樣是在父pom的 pluginManagement 中申明好的
dependencies 組件用于導入依賴,且所有 dependencies 里的依賴都會被子項目繼承。
maven依賴包?像 spring boot 這種大體量的框架,旗下子項目眾多,比如
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 組件
作用:用來申明依賴,但不導入。
dependencies 組件用于導入依賴,注意兩者區別
特性
使用 dependencyManagement 組件后,所有的子項目只需要在父pom 的 “公共依賴聲明池” 中挑選自己想要的依賴,而不用關心版本。這樣即不會繼承到不需要的依賴,又統一了依賴的版本
maven依賴管理。如果想統一調整所有子項目某個依賴的版本,只需要在父pom 里更新。不需要修改任何一個子項目。
如果某個子項目不想使用公共的版本號,只需要在 dependency 中加上版本號,子項目就會使用自定義的版本號,不會繼承父類版本號。
spring boot 就是通過這樣來統一管理依賴版本的
基于這樣的特性, dependencyManagement 組件 一般用于統一管理子項目的公共依賴的版本
依賴版本的查找
maven傳遞依賴。Maven會沿著父子層次向上走,直到找到一個擁有 dependencyManagement 組件的項目,然后在其中查找,如果找到則返回申明的依賴,沒有繼續往下找。
dependencies
dependencyManagement
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态