依賴管理是maven提供的主要功能之一。無論我們需要什么依賴,我們只需將它們添加到POM.xml中。由於maven,所有必要的類和資源都會自動添加到項目的classpath中。
在添加依賴項時,我們可以使用optional標志,或將scope設置為“provided”。在這兩種情況下,依賴關系都將在聲明它們的模塊的classpath中,但是使用將它們定義為依賴關系的模塊不會在其他項目中傳遞它們,即不會形成依賴傳遞。
從語義來上理解
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,如果此時項目中再引用的話就會造成重復引用,會有版本不一致的風險。
maven常用的scope有compile,provided,runtime,test。
1、complie是默認值,表示在build,test,runtime階段的classpath下都有依賴關系。
2、test表示只在test階段有依賴關系,例如junit。
3、provided表示在build,test階段都有依賴,在runtime時並不輸出依賴關系而是由容器提供,例如web war包都不包括servlet-api.jar,而是由tomcat等容器來提供。
4、runtime表示在構建編譯階段不需要,只在test和runtime需要。這種主要是指代碼里並沒有直接引用而是根據配置在運行時動態加載並實例化的情況。雖然用runtime的地方改成compile也不會出大問題,但是runtime的好處是可以避免在程序里意外地直接引用到原本應該動態加載的包。例如JDBC連接池。
總結
二者從功能來看,都做到了依賴不傳遞。但在語義上表示不同,使用時按場景選擇就好。