Maven的座標用來惟一標示一個項目在Maven倉庫的位置,Maven的座標主要由groupId、artifactId、version、packaging、classifier 5個元素組成,其中groupId、artifactId、version是必要的元素,而packaging、classifier能夠省略。java
groupId:定義當前項目所屬的項目包,對應了Maven倉庫中的目錄結構spring
artifactId:通常爲當前項目名稱,對應了項目名稱目錄名sql
version:項目的版本,對應了版本目錄名數據庫
packaging:指定打包的方式,默認爲jar包,可選(war、maven-plugin、pom、zip等)api
classifier:用於幫助定義構建輸出的一些附屬構建,不能直接定義一般有插件幫助生成maven
當使用座標去maven倉庫中找尋依賴文件時,將會使用如下路徑查找:ide
$RESPORITY_HOME/groupId(replace . to /)/artifactId/version/artifactId-version[-classifier].packaging (當packaging爲maven-plugin時擴展名也爲jar)工具
當version爲SNAPSHOT(快照)版本,發佈到遠程倉庫,SNAPSHOT會被替換成當時的時間戳,當在被依賴時,會時間最近時間戳的版本測試
Maven的pom文件中配置依賴大體包含下面的元素:spa
<dependency> <groupId></groupId> <artifactId></artifactId> <version></version> <type></type> <scope></scope> <optional></optional> <exclusions> <exclusion></exclusion> </exclusions> </dependency>
groupId、artifactId、version用來惟一的表示一個構建
type:依賴的類型,對應了項目座標定義時的packaging,默認爲jar
scope:依賴的範圍,可選值有compile、test、provided、runtime、system、import
optional:標記依賴是否爲可選依賴,默認爲false
exclusions:用來排除傳遞性依賴
compile:編譯範圍依賴,默認選項,對於編譯、測試、運行三個階段都須要依賴
test:測試範圍依賴,只在測試階段須要用的依賴,如junit
provided:已提供範圍依賴,對於編譯和測試階段須要此依賴,當運行期不須要,常見的如servlet-api,運行期容器提供
runtime:運行時範圍依賴,對於運行和測試階段須要此依賴,如JDBC驅動的實現,代碼在編譯時只須要JDK提供的JDBC接口
system:系統範圍依賴,與provided依賴方位同樣,只是使用system必須顯示的使用systemPath指定依賴文件路徑
import:這個依賴範圍比較特殊,並不會影響編譯、測試、運行三個階段,是用來複用某個pom文件中配置的dependencyManagement下的配置內容的,因此使用這個scope的dependency必須是知足一些條件纔有效:
(1)必須在dependencyManagement元素內
(2)packging必須爲pom
當前項目的直接依賴可能也須要依賴其餘的jar,這種依賴叫作二級依賴,Maven會使用依賴的傳遞機制幫咱們處理好二級及以上的依賴,好比以下依賴:
project -> spring-core -> commons-logging
當前項目依賴於spring-core,而spring-core又依賴於commons-logging,咱們並不須要在project的pom文件中顯示的申明commons-logging的依賴,Maven會經過spring-core的pom文件最終將commons-logging的依賴加載到project項目中,可是在依賴的傳遞過程當中也會有必定的範圍規則,以下圖:
一級依賴\二級依賴 |
compile |
test |
provided |
runtime |
compile |
compile | —— | —— |
runtime |
test |
test |
—— |
—— |
test |
provided |
provided |
—— |
provided |
provided |
runtime |
runtime |
—— |
—— |
runtime |
簡而言之就是
當二級依賴的範圍是compile時,傳遞依賴後的方位和一級依賴相同;
當二級依賴的範圍是test時,此依賴不會傳遞;
當二級依賴的範圍是provided時,只有一級依賴也爲provided纔會傳遞;
當二級依賴的範圍是runtime時,除了一級依賴爲compile,會傳遞runtime範圍,其他的範圍與一級依賴一致
當項目的間接依賴存在相同的項目不一樣的版本時,Maven不容許相同的項目被加載屢次,這時候就須要對依賴進行調解,好比:
A->B->C(1.0) ,A->D->C(2.0),A->E->F->C(3.0)
A依賴於B和D和E,但B依賴於C的1.0版本,而D依賴於C的2.0版本,F依賴於C的3.0版本,不可能A中加載三個版本的C,這樣作是顯然是不對的,因此Maven在遇到這種狀況是制定了一個規則來肯定到底加載哪一個版本的C,規則以下:
首先以依賴的深度來選擇,淺的優先,因此C(3.0)不可能被加載
在深度相同的狀況下,pom文件中先被解析到的優先
上面有提到pom文件中聲明依賴時可使用<optional>true</optional>聲明該依賴爲可選依賴,可選依賴不會被傳遞,如:
A->B,B->C(可選),B->D(可選)
想上面的C和D都不會被傳遞,須要在A的pom中明確的聲明是使用C仍是D,舉個形象的例子,B是一個持久化隔離的工具包,它支持多種數據庫,C、D能夠看做Mysql的鏈接包、Oracle的鏈接包,C、D在B的pom中的依賴聲明就是可選的,他們不會被傳遞給A,在A中須要根據實際使用的數據庫,聲明使用的鏈接包