一 、說明
我們知道m(xù)aven能幫我們管理jar包,那么它是怎么管理的呢?
二 、什么是坐標(biāo)?
1、數(shù)學(xué)中的坐標(biāo)
- 在平面上,使用 X 、Y 兩個向量可以唯一的定位平面中的任何一個點
- 在空間中,使用 X、Y、Z 三個向量可以唯一的定位空間中的任意一個點
2、Maven 中的坐標(biāo)
俗稱 gav:使用下面三個向量子倉庫中唯一定位一個 Maven 工程
在項目中的 pom.xml 文件中,我們可以看到下面gav的定義:
- groupid:公司或組織域名倒序
<groupid>com.wener</groupid> - artifactid:模塊名,也是實際項目的名稱
<artifactid>webapp</artifactid> - version:當(dāng)前項目的版本
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-RELEASE</version>
備注:
在企業(yè)的私服中,會存在snapshot快照倉庫和release發(fā)布倉庫,snapshot快照倉庫用于保存開發(fā)過程中的不穩(wěn)定版本,release正式倉庫則是用來保存穩(wěn)定的發(fā)行版本。
maven會根據(jù)模塊的版本號(pom文件中的version)中是否帶有“-SNAPSHOT”(注意這里必須是全部大寫)來判斷是快照版本還是正式版本。如果是快照版本,那么在mvn deploy時會自動發(fā)布到私服的快照版本庫中;如果是正式發(fā)布版本,那么在mvn deploy時會自動發(fā)布到正式版本庫中
三、什么是依賴?
1、概念
如果我們想要在工程中引入某個jar 包,只需要在
pom.xml中引入其jar 包的坐標(biāo)即可
2、依賴配置
配置信息
<project> <dependencies> <dependency> <groupId></groupId> <artifactId></artifactId> <version></version> <type>...</type> <scope>...</scope> <optional>...</optional> <exclusions> <exclusion> <groupId>...</groupId> <artifactId>...</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
配置說明
- dependencies
一個 pom.xml 文件中只能存在一個這樣的標(biāo)簽。用來管理依賴的總標(biāo)簽 - dependency
包含在dependencies標(biāo)簽中,可以有無數(shù)個,每一個表示一個依賴 - groupId,artifactId,version:(必要)
依賴的基本坐標(biāo),對于任何一個依賴來說,基本坐標(biāo)是最重要的,Maven根據(jù)坐標(biāo)才能找到需要的依賴。 - type(可選)
依賴的類型,對應(yīng)于項目坐標(biāo)定義的packaging。大部分情況下,該元素不必聲明,其默認(rèn)值是jar。 - scope(可選)
依賴的范圍,默認(rèn)值是 compile - optional(可選)
標(biāo)記依賴是否可選 - exclusions(可選)
用來排除傳遞性依賴,例如jar包沖突
3、依賴的范圍(scope)
- 說明
依賴范圍就是來控制 classpath(編譯、測試、運(yùn)行) 的關(guān)系,maven 的依賴范圍有如下幾種 - 可選值
- compile
編譯依賴范圍。如果沒指定,就會默認(rèn)指定該范圍。此依賴范圍的 maven 依賴對編譯、測試、運(yùn)行三種 classpath 都有效。 - test
測試依賴范圍。只對測試 classpath 有效。如,Junit。 - provided
已提供依賴范圍。此依賴范圍對編譯和測試 classpath 有效。如, servlet-api,編譯和測試的時候需要,但在項目運(yùn)行的時候,容器會提供,就不需要重復(fù)的引入。 - runtime
運(yùn)行時依賴范圍。此依賴范圍對測試和運(yùn)行 classpath 有效。如,jdbc 驅(qū)動實現(xiàn),代碼編譯只需要 jdk 提供的接口就好,測試和運(yùn)行才需要實際的 jdbc 驅(qū)動。 - system:
系統(tǒng)范圍依賴。此依賴范圍對編譯和測試 classpath 有效。不要使用。
- compile
- 示意圖
依賴范圍 編譯classpath有效 測試classpath有效 運(yùn)行時classpath有效 例子 compile Y Y Y spring-context test N Y N Junit provided Y Y N servlet-api runtime N Y Y mysql驅(qū)動 system Y Y N 本地的,maven倉庫之外的類庫文件
4、maven對傳遞依賴的解析規(guī)則。
第一原則:路徑最近者優(yōu)先
如:A->B->C->X(1.0), A->D->X(2.0),對于X構(gòu)件有2個版本1.0和2.0,因為X(1.0)的依賴長度為3,而X(2.0)的長度為2,所以maven會解析X(2.0)做為當(dāng)前構(gòu)件的依賴。
第二原則:第一聲明者優(yōu)先
如果第一原則不能解析依賴。如2個依賴的構(gòu)件的依賴長度是一樣的情況。如A->B->X(1.0)和A->C->X(2.0),X的依賴長度都是2,這時,maven會根據(jù)X1.0和X2.0在構(gòu)件中聲明的順序來決定解析哪個版本。
1、當(dāng)?shù)诙蕾嚨姆秶莄ompile的時候,傳遞性依賴的范圍與第一直接依賴的范圍一致。
2、當(dāng)?shù)诙苯右蕾嚨姆秶莟est的時候,依賴不會得以傳遞。
3、當(dāng)?shù)诙蕾嚨姆秶莗rovided的時候,只傳遞第一直接依賴范圍也為provided的依賴,且傳遞性依賴的范圍同樣為 provided;
4、當(dāng)?shù)诙苯右蕾嚨姆秶莚untime的時候,傳遞性依賴的范圍與第一直接依賴的范圍一致,但compile例外,此時傳遞的依賴范圍為runtime;
5、依賴調(diào)解
說明
在dependency元素下增加元素exclusions元素。聲明一些需要排除的傳遞性依賴。然后增加對傳遞性依賴的確切版本的依賴來解決jar版本沖突的問題。解決的方案有兩種一種是手動解決, 另外一種是通過maven helper 插件解決
解決方案
手動法
- 首先分析沖突jar包的依賴路徑,使用命令:
mvn dependency:tree -Dverbose -Dincludes=commons-logging:commons-loggging,該命令將打印出所有依賴了groupId和artifactId都為commons-logging的jar包的依賴路徑。 - 在兩個沖突的版本中,選擇一個所需的版本
- 在pom.xml文件中將沖突的依賴排除,可使用某沖突jar包
maven helper 插件
- IDEA中安裝該插件,選擇confilcts,會列出有沖突的jar,右側(cè)在要排除的版本上右鍵點擊Exclude