對於 Java 開發工程師來說,Maven 是依賴管理和代碼構建的標準。遵循「約定大於配置」理念。Maven 是 Java 開發工程師日常使用的工具,本篇文章簡要介紹一下 Maven 的依賴樹解析。
依賴樹結構
在 pom.xml 的 dependencies 中聲明依賴包後,Maven 將直接引入依賴,並通過解析直接依賴的 pom.xml 將傳遞性依賴導入到當前項目,最終形成一個樹狀的依賴結構。
原則:深度優先遍歷依賴,並緩存節點剪枝。比如下圖:
- A→B→D→E/F
- A→C→D
在第二步A→C→D
時,由於節點D已經被緩存,所以會立即返回,不必再次遍歷E/F,避免重複搜索。
依賴衝突
但是假如 2 個包同時依賴了同一個 jar 包,但是這個 jar 包版本不同,規則是什麼樣的呢?比如下圖 A 通過 B 和 D 引入了 1.0 版本的 E,同時 A 通過 C 引入了 2.0 版本的 E。針對這種多個版本構建依賴時,Maven 採用「短路徑優先」原則,即 A 會依賴 2.0 版本的 E。如果想引入 1.0 版本的 E,需要直接在 A 的 pom 中聲明 E 的版本。
如果 Java 項目過於龐大,或者依賴傳遞過於複雜時,可以使用 dependencyManagement 定義默認的版本號,一次定義全局生效,避免開發者自行管理依賴的版本。
依賴循環
比如:A 依賴了 B,同時 B 又依賴了 A。這種循環依賴可能不會直接顯現,但是可能會在一個很長的調用關係顯現出來,也可能是模塊架構的設計不合理。
我們可以使用 mvn dependency:tree -Dverbose | grep cycle
來判斷項目中是否存在「循環依賴」。
依賴排除
我們可以使用 exclusion
來解決依賴衝突,但是 exclusion
會降低 Maven 依賴解析的效率,因爲對應的 pom 文件不能緩存,每次都要重新遍歷子樹。
對於依賴排除:
-
exclusion
會造成依賴重複掃描和緩存。 - 在距離根節點越遠的
exclusion
,影響的範圍越小。 - 依賴樹高度越高,引入
exclusion
的代價越大。
依賴分析
IDEA 插件
使用 IDEA 的話,可以在對應項目中右擊,選擇 Diagrams -> Show Dependencies。
Maven 命令行
mvn dependency:tree -Dverbose