每個依賴可以包含的元素有:
groupId、artifactId、version:依賴的基本坐標,最重要
type:依賴的類型,對應(yīng)于項目坐標定義的packaging,多數(shù)情況該元素不比聲明,默認值為jar
-
scope:依賴的范圍,依賴的范圍是用來控制三種classpath(編譯classpath、測試classpath、運行classpath),maven在編譯項目主代碼、編譯執(zhí)行測試、運行maven項目時個需要三套不同的classpath。
maven主要有以下幾種依賴范圍:
compile:默認范圍。對于編譯、測試、運行三種classpath均有效。test:僅對測試classpath有效,比如JUnitprovided:編譯和測試classpath有效,但在運行時無效,比如servlet-apt,編譯測試時需要此依賴,但運行時容器已提供,因而不需要重復(fù)引入runtime:對于測試和運行classpath有效,比如JDBC驅(qū)動實現(xiàn)system:與provided范圍一致,但使用system范圍的依賴時必須通過systemPath元素顯式地指定依賴文件的路徑。由于此類依賴不是通過maven倉庫解析的,而且往往與本機系統(tǒng)綁定,可能造成構(gòu)建的不可移植,因而要慎用。systemPath可以引用環(huán)境變量。-
import:導(dǎo)入依賴范圍。不會對三種classpath產(chǎn)生實際影響。以上所有的依賴范圍均對測試有效
傳遞性依賴:當前依賴的構(gòu)件a本身有其他的依賴構(gòu)建b,導(dǎo)致maven項目需要將構(gòu)件b也導(dǎo)入,maven會自動幫助導(dǎo)入,而如果不適用maven,需要自己不斷地去添加構(gòu)件,麻煩!
依賴范圍會影響傳遞性依賴,好比A依賴于B,B依賴于C,稱A對于B是第一直接依賴,B對于C是第二直接依賴,二者決定了傳遞性依賴的范圍,見下表。
依賴傳遞對依賴范圍的影響.png
依賴調(diào)解:對于傳遞依賴,可能存在的情況是如下A->B->x(1.0)和A->D->F->x(2.0)和A->K->x(3.0),maven采用兩條原則,路徑最近者原則和第一聲明者原則,如上,最終選擇x(1.0)
-
optional:標記依賴是否可選,值為true和false。
存在一些情況如下:A依賴于B,B依賴于C和D,C和D對于B都是可選依賴(C和D可能是互斥的因而可選),即A->B,B->C(可選),B->D(可選),此時C和D不會對A造成傳遞依賴,因此,如果A依賴于B,B使用的C的函數(shù),則A需要顯示聲明C這一依賴。
理想情況下,可選依賴不應(yīng)該被使用,除非某項目為了實現(xiàn)多個特性。然而,在面向?qū)ο笤O(shè)計中,有單一職責原則。
-
exclusions:排除傳遞性依賴
存在一些情況如下:傳遞依賴A->B->C- C是一個SNAPSHOT版本,不穩(wěn)定,此時需要排除掉這個C換為其他并且顯式聲明;
- C不在maven的中央倉庫,需要使用另外一個替代C。需要注意的是,聲明excusion的時候只需要groupId和artifactId,不需要version,因為依賴圖中通過groupId和artifactId即可唯一定位此依賴,不可能存在groupId和artifactId相同但是version不同的兩個依賴
多數(shù)依賴聲明只包含基本坐標。
歸類依賴:相當于提取出常量為public final
優(yōu)化依賴:去除多余依賴,顯示聲明必要的依賴。
mvn dependency:list 查看當前所有已解析依賴
mvn dependency:tree 將以上展示為依賴樹
mvn dependency:analyze 結(jié)果會分為兩個部分——未顯示聲明的依賴、項目中未使用的但是顯示聲明的依賴。
對于前者,需要顯示聲明項目中直接用到的依賴。
對于后者,此命令只分析編譯主代碼和測試代碼需要用到的依賴,對于一些執(zhí)行測試和運行的依賴無法檢測,需要慎重刪除。
