1.Maven中依賴概述
Maven 中的依賴關(guān)系是有傳遞性的嘶窄。例如:項(xiàng)目B依賴項(xiàng)目C(B —> C)坎吻,如果有一個(gè)項(xiàng)目A依賴項(xiàng)目B(A —> B)的話硬霍,那么項(xiàng)目A也會(huì)依賴項(xiàng)目C(A —> C)。雖然井佑,這種依賴的自動(dòng)傳遞性給我們維護(hù)項(xiàng)目的必要依賴關(guān)系帶來(lái)了極大地幫助,但當(dāng)我們?cè)谀承┣闆r下眠寿,需要在項(xiàng)目A中排除對(duì)項(xiàng)目C的依賴時(shí)躬翁,這時(shí)又該怎么做呢?Maven 為我們提供了兩種解決方案澜公,分別是可選依賴(Optional Dependencies)和依賴排除(Dependency Exclusions)姆另。
2.哪些場(chǎng)景需要排除依賴
我們繼續(xù)用上文中的例子,雖然項(xiàng)目A依賴項(xiàng)目B坟乾,但當(dāng)項(xiàng)目A不是完全依賴項(xiàng)目B的時(shí)候迹辐,即項(xiàng)目A只用到了項(xiàng)目B的一部分功能,而正巧項(xiàng)目B這部分功能的實(shí)現(xiàn)甚侣,并不需要依賴于項(xiàng)目C明吩,這個(gè)時(shí)候,項(xiàng)目A就應(yīng)該排除對(duì)項(xiàng)目C的依賴殷费。
有的人可能有這樣的疑問(wèn)印荔,為什么要排除對(duì)項(xiàng)目C的依賴呢?就算包含了對(duì)項(xiàng)目C的依賴详羡,也不會(huì)出問(wèn)題啊仍律。事實(shí)上,表面上看確實(shí)不會(huì)出現(xiàn)問(wèn)題实柠。但是水泉,我們必須記住一點(diǎn):當(dāng)我們使用一個(gè)工程時(shí),控制實(shí)際需要的依賴列表非常重要窒盐。而且草则,排除不必要的依賴還可以幫助我們,節(jié)約磁盤蟹漓、內(nèi)存等空間炕横,避免許可協(xié)議問(wèn)題以及類路徑問(wèn)題等。我們?cè)谙硎?strong>Maven依賴的自動(dòng)傳遞性帶給我們的便利的同時(shí)葡粒,要時(shí)刻注意引入冗余份殿、不必要的依賴對(duì)我們項(xiàng)目產(chǎn)生的負(fù)面影響。
3.可選依賴(Optional Dependencies)—— optional
從項(xiàng)目B入手嗽交,使項(xiàng)目A依賴項(xiàng)目B時(shí)伯铣,排除對(duì)項(xiàng)目C的依賴。項(xiàng)目B的配置片段如下:
<project>
...
<dependencies>
<dependency>
<groupId>sample.ProjectC</groupId>
<artifactId>Project-C</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>
在項(xiàng)目A中按照正常的方式引入對(duì)項(xiàng)目B的依賴即可轮纫,這個(gè)時(shí)候,項(xiàng)目A就不會(huì)依賴項(xiàng)目C了焚鲜。如果項(xiàng)目A用到了項(xiàng)目B中涉及項(xiàng)目C的功能掌唾,則需要在項(xiàng)目A的 pom.xml
文件中額外配置對(duì)項(xiàng)目C的依賴放前。
應(yīng)用場(chǎng)景:假設(shè)有一個(gè)項(xiàng)目X,它實(shí)現(xiàn)了類似Hibernate的功能糯彬,支持很多種數(shù)據(jù)庫(kù)驅(qū)動(dòng)凭语,例如:mysql,oracle等撩扒。我們?cè)跇?gòu)建項(xiàng)目X的時(shí)候似扔,確實(shí)需要所有這些依賴。但設(shè)想搓谆,假如有一個(gè)項(xiàng)目Y想使用項(xiàng)目X提供的功能炒辉,那么它極有可能只使用其中的一種數(shù)據(jù)庫(kù)驅(qū)動(dòng)。這個(gè)時(shí)候泉手,就需要我們?cè)陧?xiàng)目X中將所有和驅(qū)動(dòng)相關(guān)的依賴設(shè)置為可選依賴黔寇。只有這樣,在項(xiàng)目Y中聲明項(xiàng)目X為直接依賴的時(shí)候斩萌,才不會(huì)將項(xiàng)目X的所有關(guān)于驅(qū)動(dòng)的依賴自動(dòng)引入缝裤。這時(shí),項(xiàng)目Y只需要額外聲明自己真正需要依賴的驅(qū)動(dòng)即可颊郎。
4.依賴排除(Dependency Exclusions)—— exclusion
接上文例子憋飞,如果項(xiàng)目B沒(méi)有把項(xiàng)目C設(shè)置為可選依賴(Optional Dependencies),而項(xiàng)目A又想在依賴項(xiàng)目B的同時(shí)不依賴項(xiàng)目C姆吭,應(yīng)該如何操作呢榛做?這個(gè)時(shí)候,我們使用依賴排除(Dependency Exclusions)就可以達(dá)到目的猾编。此時(shí)瘤睹,項(xiàng)目B按照正常的方式引入對(duì)項(xiàng)目C的依賴,項(xiàng)目A在引入對(duì)項(xiàng)目B的依賴時(shí)答倡,配置如下:
<project>
...
<dependencies>
<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>sample.ProjectC</groupId>
<artifactId>Project-C</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
應(yīng)用場(chǎng)景:接上文例子轰传,假如項(xiàng)目X并沒(méi)有將所有對(duì)驅(qū)動(dòng)的依賴設(shè)置為可選依賴(Optional Dependencies),那么項(xiàng)目Y直接引入對(duì)項(xiàng)目X的依賴時(shí)瘪撇,就會(huì)將項(xiàng)目X中所有對(duì)驅(qū)動(dòng)的依賴一起引入获茬。這時(shí)候,就需要我們?cè)谝腠?xiàng)目X時(shí)通過(guò)依賴排除(Dependency Exclusions)去除掉我們不需要的那些依賴倔既。
需要注意的是恕曲,依賴排除(Dependency Exclusions)是基于單個(gè)依賴的,并不是POM級(jí)別的渤涌。也就是說(shuō)佩谣,雖然,項(xiàng)目A在引入對(duì)項(xiàng)目B的依賴時(shí)实蓬,排除了對(duì)項(xiàng)目C的依賴茸俭。但吊履,并不影響項(xiàng)目A在其他地方引入對(duì)項(xiàng)目C的依賴。例如调鬓,項(xiàng)目A又引入了對(duì)項(xiàng)目D的依賴艇炎,而項(xiàng)目D依賴項(xiàng)目C,這個(gè)時(shí)候腾窝,項(xiàng)目A就又產(chǎn)生了對(duì)項(xiàng)目C的依賴缀踪。
另外,在Maven引入的jar包發(fā)生沖突時(shí)虹脯,也往往需要借助依賴排除(Dependency Exclusions)來(lái)解決驴娃。