傳遞依賴
依賴管理是maven提供的主要功能之一,無論我們需要什么依賴,只需將它們添加到 POM.xml 中,在構建或運行時所有必要的類和資源都會自動添加到專案的 classpath 中,
Maven 中的依賴是有傳遞(Transitive)性的,默認會包含傳遞的依賴,這樣就不用手動參考每一個依賴了,比如下面這個依賴關系中,A 依賴 B,B 依賴了 C……,如果你依賴 A 的話,就會自動包含 A/B/C/D/E
A
├── B
│ └── C
│ └── D
└── E
└── D
但是傳遞依賴也帶來了一個問題,比如下面這個例子:
A
├── B
│ └── C
│ └── D 2.0
└── E
└── D 1.0
由于傳遞依賴,D 2.0 和 D 1.0 都會被加入 ClassPath 中,但因為它們版本不同,很可能會有包沖突等一系列問題,解決這個依賴傳遞導致的沖突問題,有兩種方案:
1. 在使用者,也就是發起依賴方進行排除
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
2.在提供方,將依賴的范圍定義為不傳遞,這樣在構建時就不會包含這些不傳遞的依賴包了,不傳遞的配置有兩種方式
2.1 定義 dependency scope 為 provided
<dependency>
<groupId>group</groupId>
<artifactId>artifact-d</artifactId>
<version>2.0</version>
<!-- 不傳遞 -->
<scope>provided</scope>
</dependency>
2.2 定義 <optional>
<dependency> <groupId>group</groupId> <artifactId>artifact-d</artifactId> <version>2.0</version> <!-- 不傳遞 --> <optional>true</optional> </dependency>
在添加依賴項時,我們可以使用 <optional>true</optional> 標志:
在這兩種不傳遞配置下,依賴關系都將在宣告它們的模塊的 classpath 中,但是使用將它們定義為依賴關系的模塊不會在其他專案中傳遞它們,即不會形成依賴傳遞,
那<optional>和 provided scope 之間又有什么區別呢?
從語意來上理解
optional
可選的,可以理解為此功能/此依賴可選,如果不需要某項功能,可以不參考這個包,
scope provided
提供的,可以理解為此包不由我直接提供,需要呼叫者/容器提供,
舉個例子說明二者的使用場景和區別
optional
現開發了一個類似Hibernate的框架,叫Summer吧,致敬下Spring,提供了多種資料庫方言的支持:mysql/oracle/db2/postgresql...
每種資料庫支持也獨立了一個module,Summer的依賴中配置了每種資料庫的支持包:summer-mysql-support/summer-oracle-support...
但是實際參考此框架/依賴時,并不需要所有資料庫方言的支持,此時可以把資料庫的支持包都配置為可選的<optional>true</optional>,
參考此框架時,只需按需引入自己需要的方言支持包即可,避免了冗余繁雜的依賴,也降低了jar包沖突的風險,
scope provided
現有一普通Web工程,必然會用到servlet-api這個包,但是實際上這個包一定是由容器提供的,因為我們這個web會部署到容器內,容器會提供servlet-api,如果此時專案中再參考的話就會造成重復參考,會有版本不一致的風險,
總結
二者從功能來看,都做到了依賴不傳遞,但在語意上表示不同,使用時按場景選擇就好,
原文鏈接:https://segmentfault.com/a/1190000019266080?utm_source=tag-newest
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/547628.html
標籤:其他
上一篇:[嵌入式RTOS]記錄一下因浮點數轉為字串導致精度損失所踩的坑
下一篇:Stream流
