在開發 spring boot 項目時,你是否遇到過,有些依賴即便不寫版本號也能下載到某一版本的依賴。java
好比下面這個案例mysql
pom文件web
<?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>
下配置了三個依賴項redis
這個項目雖然引用了三個依賴,但只有 mybatis-spring-boot-starter 這個依賴是寫了版本號的,其他兩個沒寫。spring
咱們知道導入一個依賴須要提供依賴的座標 (groupId、artifactId、version)sql
參考 maven 座標apache
既然 spring-boot-starter-web 和 mysql-connector-java 沒有提供 version,那麼應該沒法正確下載依賴纔對。bash
但實際狀況如圖 mybatis
不知道你們注意到沒,該 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 的版本號就在裏面
下面是 spring-boot-dependencies-2.1.9.RELEASE.pom 中的部份內容
注意如下三個組件
其中 properties 定義了一系列的版本號,而且在 dependencyManagement 中使用了版本號。注意這個 dependencyManagement,它的下級是咱們最經常使用的 dependencies 組件
咱們知道 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 裏的依賴都會被子項目繼承。
像 spring boot 這種大致量的框架,旗下子項目衆多,好比
這些子項目也有各自的依賴,其中有些依賴是公共的,好比
spring-boot-starter-web-2.1.9.RELEASE 和 spring-boot-starter-data-redis--2.1.9.RELEASE 的依賴結構以下
如何保證全部子項目的公共依賴的版本一致呢,總不能在每一個子項目裏寫死吧,這樣手動去管理得累死。
因此 spring boot 將全部公共依賴抽離出來,放到 spring-boot-dependencies 中來管理。 全部的子項目都直接或間接繼承自 spring-boot-dependencies,這樣同一個版本的全部的子項目的公共依賴就都同樣了。
但這樣作帶來了一個問題,每一個子項目都繼承了全部都公共依賴,解決這件事情,就須要使用 maven 的 dependencyManagement 組件
做用:用來申明依賴,但不導入。
dependencies 組件用於導入依賴,注意二者區別
特性
使用 dependencyManagement 組件後,全部的子項目只須要在父pom 的 「公共依賴聲明池」 中挑選本身想要的依賴,而不用關心版本。這樣即不會繼承到不須要的依賴,又統一了依賴的版本
若是想統一調整全部子項目某個依賴的版本,只須要在父pom 裏更新。不須要修改任何一個子項目。
若是某個子項目不想使用公共的版本號,只須要在 dependency 中加上版本號,子項目就會使用自定義的版本號,不會繼承父類版本號。
spring boot 就是經過這樣來統一管理依賴版本的
基於這樣的特性, dependencyManagement 組件 通常用於統一管理子項目的公共依賴的版本
Maven會沿着父子層次向上走,直到找到一個擁有 dependencyManagement 組件的項目,而後在其中查找,若是找到則返回申明的依賴,沒有繼續往下找。
dependencies
dependencyManagement