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

可見(jiàn)second項(xiàng)目?jī)H僅是引入了first項(xiàng)目,但為什么外部庫(kù)中包含了lombok依賴呢?這是因?yàn)?code>first依賴lombok,而second依賴first時(shí),lombok也被傳遞給了second。

同樣地,如果現(xiàn)在又有一個(gè)項(xiàng)目third依賴second呢?那么third也會(huì)間接依賴lombok,也可以使用lombok中的類。
當(dāng)然,依賴并不總是會(huì)傳遞的,有下列因素會(huì)影響依賴傳遞。
(1) scope作用域
scope不僅僅代表這個(gè)依賴的作用域,也會(huì)影響依賴的傳遞,只有scope為compile和runtime的依賴是會(huì)傳遞的。
假設(shè)現(xiàn)在把上述first項(xiàng)目中的lombok依賴scope改成provided或者test,然后重新執(zhí)行mvn clean install,你就會(huì)發(fā)現(xiàn)在second的依賴中,就看不到lombok了!
(2) optional字段
除了scope之外,還可以設(shè)定依賴的optional字段,當(dāng)設(shè)定為true時(shí)代表這個(gè)依賴是可選的,那么這時(shí)無(wú)論其scope是什么,這個(gè)依賴都不會(huì)傳遞。默認(rèn)情況下,即不聲明依賴的optional字段時(shí),它的值是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項(xiàng)目,你就會(huì)發(fā)現(xiàn)lombok依賴就沒(méi)有傳遞過(guò)來(lái)了!

所以如果在制作外部庫(kù)需要其他人引用的時(shí)候,我們可以將一些僅僅是外部庫(kù)需要使用但是其它項(xiàng)目不一定要使用的依賴的optional設(shè)定為true,避免其他開發(fā)者引入你的外部庫(kù)時(shí)發(fā)生依賴沖突。
到此這篇關(guān)于Maven依賴作用域和依賴傳遞的使用的文章就介紹到這了,更多相關(guān)Maven依賴作用域和依賴傳遞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot設(shè)置接口超時(shí)時(shí)間的方法
這篇文章主要介紹了SpringBoot設(shè)置接口超時(shí)時(shí)間的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
spring boot openfeign從此和httpClient說(shuō)再見(jiàn)詳析
這篇文章主要給大家介紹了關(guān)于spring boot openfeign從此和httpClient說(shuō)再見(jiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧2018-06-06
Java中Spring MVC接收表單數(shù)據(jù)的常用方法
Spring MVC是Spring框架中的一個(gè)模塊,用于開發(fā)基于MVC(Model-View-Controller)架構(gòu)的Web應(yīng)用程序,它提供了一種輕量級(jí)的、靈活的方式來(lái)構(gòu)建Web應(yīng)用,同時(shí)提供了豐富的功能和特性,本文給大家介紹了Spring MVC接收表單數(shù)據(jù)的方法,需要的朋友可以參考下2024-05-05
詳解如何在Java項(xiàng)目中實(shí)現(xiàn)信號(hào)的連續(xù)接收
在Java項(xiàng)目中,信號(hào)的連續(xù)接收是一項(xiàng)重要的任務(wù),特別是在處理異步事件或者需要對(duì)外部事件做出響應(yīng)時(shí),本篇博客將介紹如何在Java項(xiàng)目中實(shí)現(xiàn)信號(hào)的連續(xù)接收,包括信號(hào)的監(jiān)聽、處理和停止等步驟,需要的朋友可以參考下2023-11-11
spring boot整合mybatis+mybatis-plus的示例代碼
這篇文章主要介紹了spring boot整合mybatis+mybatis-plus的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
SpringBoot工程中Spring Security應(yīng)用實(shí)踐記錄流程分析
Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架。這篇文章主要介紹了SpringBoot工程中Spring Security應(yīng)用實(shí)踐,需要的朋友可以參考下2021-09-09

