Maven依賴作用域和依賴傳遞的使用
在Java項目開發(fā)中,Maven是我們最常用的依賴管理和構(gòu)建工具了!我們常常通過添加dependency節(jié)點,就能夠很方便地加入依賴,而不需要我們自己去手動下載jar文件并引入。
今天主要是來總結(jié)一下在Maven中依賴的作用域和傳遞。
1,依賴作用域
通過在每個dependency中設定scope字段,即可聲明其作用域,例如:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <!-- 聲明作用域 --> <scope>provided</scope> </dependency>
上面我們就設定了lombok這個依賴的作用域為provided。
常用的作用域字段值及其意義如下:
compile這是默認的scope(即你不寫scope字段的話,這個依賴作用域就是compile),表示依賴在編譯、測試和運行時都是可用的,并且會參與項目的打包過程,該依賴會傳遞給依賴該模塊的其他模塊provided表示依賴在編譯和測試時是可用的,但該依賴不會參與程序運行階段,即程序運行時無法調(diào)用該依賴中的類,它不會參與項目的打包過程,也不會傳遞給其他模塊runtime表示依賴僅在運行時是可用的,但在編譯和測試時不需要,它會傳遞給依賴該模塊的其他模塊,但不會參與項目的打包過程test表示依賴只在測試和運行時使用,不會參與項目的打包過程,也不會傳遞給其他模塊
可見一個Maven項目,從編譯到運行會經(jīng)歷三個階段:編譯 → 測試 → 運行
不同作用域在三個階段的可見性如下表:
| 編譯時可用 | 測試時可用 | 運行時可用 | |
|---|---|---|---|
compile | √ | √ | √ |
provided | √ | √ | x |
runtime | x | √ | √ |
test | x | √ | x |
2,作用域和打包
我們常常會使用maven-assembly-plugin插件,讓我們在打包的時候?qū)⑺械囊蕾嚩即虬磷詈蟮?code>jar文件中,使得jar文件可以直接運行。
不過真的是所有的依賴都會被打包到最后的jar中嗎?
其實并不是,在使用maven-assembly-plugin插件插件時,默認只有scope為compile和runtime的依賴才會被包含在最終的結(jié)果中。
因此,為了減小最終jar的大小,我們應當將運行時不需要的依賴設置為provided或者test,當然這也是根據(jù)用途選擇。
例如lombok依賴會在編譯的時候生成getter和setter的代碼,但是運行的時候這個依賴就不需要了,因此它常常被設定為provided。
但是在Spring Boot開發(fā)中就不一樣了,Spring Boot工程中,使用的是spring-boot-maven-plugin,這個插件也能完成同樣的目的,即打包時將所有的依賴全部打包到一個jar中,但是這個插件會將所有的依賴都打包進去,無論其scope是什么。
不過,我們可以在這個插件中進行配置,聲明打包時需要排除的依賴,例如:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <!-- 打包時排除lombok依賴 --> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin>
3,依賴的傳遞
事實上,在Maven中,依賴也是會傳遞的,我們先創(chuàng)建一個名為first的項目,并引入lombok依賴如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.swsk33</groupId>
<artifactId>first</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 引入lombok依賴 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
</dependencies>
</project>這是項目first的pom.xml文件,其groupId為com.gitee.swsk33,其artifactId為first,其版本為1.0.0,現(xiàn)在在其工程目錄下執(zhí)行mvn clean install安裝至本地倉庫使得待會可以引用它。
現(xiàn)在在新建項目second,并引用上述的first作為依賴,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.swsk33</groupId>
<artifactId>second</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 引用first項目 -->
<dependency>
<groupId>com.gitee.swsk33</groupId>
<artifactId>first</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>好的,現(xiàn)在展開IDEA左側(cè)欄的外部庫部分,看看second項目的依賴:

可見second項目僅僅是引入了first項目,但為什么外部庫中包含了lombok依賴呢?這是因為first依賴lombok,而second依賴first時,lombok也被傳遞給了second。

同樣地,如果現(xiàn)在又有一個項目third依賴second呢?那么third也會間接依賴lombok,也可以使用lombok中的類。
當然,依賴并不總是會傳遞的,有下列因素會影響依賴傳遞。
(1) scope作用域
scope不僅僅代表這個依賴的作用域,也會影響依賴的傳遞,只有scope為compile和runtime的依賴是會傳遞的。
假設現(xiàn)在把上述first項目中的lombok依賴scope改成provided或者test,然后重新執(zhí)行mvn clean install,你就會發(fā)現(xiàn)在second的依賴中,就看不到lombok了!
(2) optional字段
除了scope之外,還可以設定依賴的optional字段,當設定為true時代表這個依賴是可選的,那么這時無論其scope是什么,這個依賴都不會傳遞。默認情況下,即不聲明依賴的optional字段時,它的值是false。
現(xiàn)在將first中的lombok依賴的optional字段聲明為true:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <optional>true</optional> </dependency>
然后重新mvn clean install,再次打開second項目,你就會發(fā)現(xiàn)lombok依賴就沒有傳遞過來了!

所以如果在制作外部庫需要其他人引用的時候,我們可以將一些僅僅是外部庫需要使用但是其它項目不一定要使用的依賴的optional設定為true,避免其他開發(fā)者引入你的外部庫時發(fā)生依賴沖突。
到此這篇關(guān)于Maven依賴作用域和依賴傳遞的使用的文章就介紹到這了,更多相關(guān)Maven依賴作用域和依賴傳遞內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Error occurred during initialization o
這篇文章主要介紹了解決Error occurred during initialization of VM Java虛擬機初始化失敗問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
SSH框架網(wǎng)上商城項目第16戰(zhàn)之Hibernate二級緩存處理首頁熱門顯示
這篇文章主要介紹了SSH框架網(wǎng)上商城項目第16戰(zhàn)之Hibernate的二級緩存處理首頁的熱門顯示,感興趣的小伙伴們可以參考一下2016-06-06
SpringSecurity拋出異常但AccessDeniedHandler不生效的解決
本文主要介紹了SpringSecurity拋出異常但AccessDeniedHandler不生效的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-01-01

