1. 程式人生 > 實用技巧 >Maven依賴關係原則

Maven依賴關係原則

轉載自: Maven依賴關係原則與衝突解決辦法(含必殺技) 筆者JustryDeng

Maven依賴關係原則(概念):

相關概念:

級別:

我們不妨把pom.xml裡面的引用的依賴視為第一級,那麼依賴中各自引用的依賴視為第二級...第三級...

路徑長短:

我們不妨以從pom.xml出發,到抵達該依賴時經過的“級”的個數來作為路徑長短的標準。

最短路徑(不同級引用)原則:

若兩個版本不同的同一依賴,在不同的級別中,那麼優先使用路徑最短的那一個,如:

同級(第一級遵循最後、其它級遵循最先)引用原則:

同級別的引用,分兩種:
兩個不同版本的同一依賴,所在的級別是第一級;兩個不同版本的同一依賴,所在的級別不是第一級。

  • 在第一級,誰後宣告,使用誰:

  • 不在第一級,誰先宣告,使用誰:


Maven依賴關係原則(測試驗證):

提示:這裡只給出測試原理及結果,具體的測試程式碼、測試專案本人託管在Github上,具體連結見本文末尾。

  • 測試專案結構及測試原理說明:

fastjson-1.2.10版本與fastjson-1.2.11版本差別較大,如果是1.2.11版的話,可以在程式碼中直接new FastJsonConfig();而如果是1.2.10版的話,直接在程式碼中new FastJsonConfig()的話,是會報錯的。在這個的基礎上,我們可以通過在a模組兒中直接或間接(通過引入其他模組兒來)引入fastjson的依賴,來判斷maven最終引用的是哪一個版本的依賴,進而測試上面的結論。

  • 測試最短路徑:

  • 測試(第一級)最後引用:

  • 測試(非第一級)最先引用:

注:按本文中約定的定義,上圖中的依賴關係中,d、e是第一級別,fastjson是第二級別。


Maven(依賴)衝突解決辦法:

第一種:使用【exclusions】排除不需要的依賴。

第二種:使用【dependencyManagement】指定使用哪一個版本的依賴。

注:dependencyManagement的作用有兩個:一是指定使用某個依賴的哪一個版本。二是統一管理版本
在dependencyManagement指定版本號後,在與dependencyManagement同級的
dependencies標籤裡面,引入依賴時,就可以不指定版本號了。

注:maven官網是這麼介紹Dependency Management的:

Dependency Management

Besides inheriting certain top-level elements, parents have elements to configure values for child POMs and transitive dependencies. One of those elements is dependencyManagement.

dependencyManagement: is used by a POM to help manage dependency information across all of its children. If the my-parent project uses dependencyManagement to define a dependency on junit:junit:4.12, then POMs inheriting from this one can set their dependency giving the groupId=junit and artifactId=junit only and Maven will fill in the version set by the parent. The benefits of this method are obvious. Dependency details can be set in one central location, which propagates to all inheriting POMs.

Note that the version and scope of artifacts which are incorporated from transitive dependencies are also controlled by version specifications in a dependency management section. This can lead to unexpected consequences. Consider a case in which your project uses two dependences, dep1 and dep2. dep2 in turn also uses dep1, and requires a particular minimum version to function. If you then use dependencyManagement to specify an older version, dep2 will be forced to use the older version, and fail. So, you must be careful to check the entire dependency tree to avoid this problem; mvn dependency:tree is helpful.

第三種(必殺):直接在jar包中刪除衝突了的(多餘的那個依賴)對應的package包。

第一種第二種方式就能解決所有maven管轄範圍內的依賴衝突了。大部分難以解決的衝突,幾乎都是由於引入了jar包而引起的。這裡介紹如何解決jar包引起的衝突:使用解壓工具(如rar)直接刪除jar包裡面的不需要的依賴對應的包

場景舉例說明:

筆者最近使用使用到了某考勤廠商的sdk依賴jar包。該jar包有點特殊,是由gradle構建的,而且貌似構建得不規範;本人將其引入SpringBoot專案後,發生衝突了,需要將該jar包裡面的低版本的fastjson去掉;第一種第二種方式都試了,再網上找了一圈頁首找到有效的解決辦法,然後回頭一想:只要當前環境中存在該jar包需要的依賴就可以了,至於在不在該jar裡面就無所謂了,所以我直接使用rar刪除了該jar包裡面不要的fastjosn包,然後重新將jar包匯入專案,衝突就解決了。

刪除後,關閉。再次開啟jar包,發現fastjson對應的包已經沒了。