Maven中optional和scope元素的使用弄明白了嗎
在梳理項(xiàng)目的過(guò)程中發(fā)現(xiàn)很多開(kāi)發(fā)同學(xué)對(duì) Maven 依賴文件的配置并不了解,特別是對(duì) Maven 的 optional 元素和 scope 元素的使用也非常隨意。這就會(huì)導(dǎo)致發(fā)布的 jar 包或 war 包非常 “胖”、編譯速度慢,而且還很容易生產(chǎn) jar 沖突等問(wèn)題。本篇文章從 optional 和 scope 的使用場(chǎng)景入手,讓項(xiàng)目實(shí)現(xiàn)一波瘦身。
optional 元素
這里以 Spring Boot 項(xiàng)目中的使用為例,比如我們?cè)陧?xiàng)目中經(jīng)常使用的熱部署組件 spring-boot-devtools,就可以使用 optional 元素來(lái)進(jìn)行定義,對(duì)應(yīng) pom 文件中配置如下:
<!--devtools 熱部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
那么,這里的 optional 元素設(shè)置為 true 表示何意?optional 是 Maven 依賴 jar 時(shí)的一個(gè)選項(xiàng),表示該依賴是可選的,項(xiàng)目之間依賴不傳遞。不設(shè)置 optional(默認(rèn))或者 optional 是 false,表示傳遞依賴。
文字描述可能比較抽象,下面用具體實(shí)例場(chǎng)景來(lái)進(jìn)行更直觀的描述,這里假設(shè)有兩個(gè)項(xiàng)目 A 和 B,其中 A 為父項(xiàng)目,B 為子項(xiàng)目。在父項(xiàng)目中引入了單元測(cè)試的依賴:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
下面針對(duì) optional 元素的不同值進(jìn)行講解。
optional 元素默認(rèn)值(false)
當(dāng)父項(xiàng)目添加 junit 依賴時(shí),并未添加 optional 選項(xiàng),也就是默認(rèn)的 optional 元素的值為 false。
此時(shí),當(dāng)子項(xiàng)目依賴父項(xiàng)目時(shí),父項(xiàng)目 A 和子項(xiàng)目 B 的關(guān)系如下:
父項(xiàng)目并未設(shè)置 optional 元素為 true,那么便具有依賴傳遞性。此時(shí),子項(xiàng)目 B 中會(huì)直接引入父項(xiàng)目 A 中引入的 Junit 的 jar 包。也就是說(shuō) B 項(xiàng)目打包時(shí),jar/war 包中會(huì)包含 junit 的 jar 包。
optional 元素為 true
當(dāng)父項(xiàng)目引入 junit 依賴時(shí),設(shè)置 optional 元素為 true。那么,子項(xiàng)目 B 便有了更多的選擇。
如果項(xiàng)目 B 不需要 Junit 的 jar 包,那么在其 pom 文件中不需進(jìn)行任何處理便可以。如果 B 項(xiàng)目也需要對(duì)應(yīng)的 jar 包依賴,可以有兩種選擇:第一、A 項(xiàng)目中對(duì)應(yīng)依賴的 optional 設(shè)置為 false 或去掉;第二、B 項(xiàng)目中直接引入需要的該依賴。
parent 繼承的情況
我們經(jīng)常會(huì)在 parent 項(xiàng)目中配置統(tǒng)一的依賴版本控制,如下:
<dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <optional>true</optional> </dependency> </dependencies> </dependencyManagement>
此時(shí),如果 B 項(xiàng)目需要 Junit 的 jar 包,可以直接在項(xiàng)目中引入,這里父項(xiàng)目中的 optional 配置對(duì)子項(xiàng)目并無(wú)影響。
綜上所述,在 Maven 項(xiàng)目中,恰當(dāng)?shù)氖褂?optional 配置,可以在很大程度上減少 jar 包的大小,提升編譯和發(fā)布速度。
scope 元素
上面講完了 optional 元素的使用,再來(lái)看看 scope 的使用。
scope 元素主要用來(lái)控制依賴的使用范圍,指定當(dāng)前包的依賴范圍和依賴的傳遞性,也就是哪些依賴在哪些 classpath 中可用。常見(jiàn)的可選值有:compile, provided, runtime, test, system 等。
compile(編譯)
默認(rèn)值。compile 表示對(duì)應(yīng)依賴會(huì)參與當(dāng)前項(xiàng)目的編譯、測(cè)試、運(yùn)行等,是一個(gè)比較強(qiáng)的依賴。打包時(shí)通常會(huì)包含該依賴,部署時(shí)會(huì)打包到 lib 目錄下。比如:spring-core 這些核心的 jar 包。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
test(測(cè)試)
scope 為 test 表示依賴項(xiàng)目?jī)H參與測(cè)試環(huán)節(jié),在編譯、運(yùn)行、打包時(shí)不會(huì)使用。最常見(jiàn)的使用就是單元測(cè)試類(lèi)了:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
類(lèi)似單元測(cè)試這樣的依賴,如果不設(shè)置 scope 為 test,很顯然它們會(huì)被打包、發(fā)布,但其實(shí)真是環(huán)境中并無(wú)什么作用。
runntime(運(yùn)行時(shí))
runntime 僅僅適用于運(yùn)行和測(cè)試環(huán)節(jié),在編譯環(huán)境下不會(huì)被使用。比如編譯時(shí)只需要 JDBC API 的 jar,而只有運(yùn)行時(shí)才需要 JDBC 驅(qū)動(dòng)實(shí)現(xiàn)。
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> <scope>runtime</scope> </dependency>
provided(已提供)
provided 適合在編譯和測(cè)試的環(huán)境,和 compile 功能相似,但 provide 僅在編譯和測(cè)試階段生效,provide 不會(huì)被打包,也不具有傳遞性。
比如:上面講到的 spring-boot-devtools、servlet-api 等,前者是因?yàn)椴恍枰谏a(chǎn)中熱部署,后者是因?yàn)槿萜饕呀?jīng)提供,不需要重復(fù)引入。
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency>
system
system 范圍依賴與 provided 類(lèi)似,不過(guò)依賴項(xiàng)不會(huì)從 maven 倉(cāng)庫(kù)獲取,而需要從本地文件系統(tǒng)提供。使用時(shí),一定要配合 systemPath 屬性。不推薦使用,盡量從 Maven 庫(kù)中引用依賴。
<dependency> <groupId>sun.jdk</groupId> <artifactId>tools</artifactId> <version>1.5.0</version> <scope>system</scope> <systemPath>${java.home}/../lib/tools.jar</systemPath> </dependency>
scope 依賴的傳遞性
上面講解 scope 的不同參數(shù)值,針對(duì)這些參數(shù)值,在多個(gè)項(xiàng)目中的依賴傳遞性如下:
其中 B 依賴 A,C 依賴 B,傳遞性的關(guān)鍵是 B 依賴 A 時(shí)所設(shè)置的 scope 值,當(dāng) B 采用不同的值時(shí)對(duì)應(yīng)的依賴關(guān)系如下:當(dāng) B 通過(guò) test 或 provided 依賴 A 時(shí),C 不依賴 A;當(dāng) B 通過(guò) runtime 或 compile 依賴 A 時(shí),C 依賴 A;
小結(jié)
經(jīng)過(guò)上面對(duì) Maven 的 optional 和 scope 元素的詳細(xì)講解,想必你已經(jīng)可以對(duì)項(xiàng)目中的配置進(jìn)行排查,確保精確的使用項(xiàng)目與項(xiàng)目之間的依賴,而不是每個(gè)項(xiàng)目都引入大而全的依賴文件,導(dǎo)致項(xiàng)目臃腫,編譯緩慢,沖突不斷。
到此這篇關(guān)于Maven中optional和scope元素的使用弄明白了嗎的文章就介紹到這了,更多相關(guān)Maven optional scope 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何基于Idea遠(yuǎn)程調(diào)試tomcat war包及jar包
這篇文章主要介紹了如何基于Idea遠(yuǎn)程調(diào)試tomcat war包及jar包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08java N皇后實(shí)現(xiàn)問(wèn)題解析
將 n 個(gè)皇后擺放在一個(gè) n x n 的棋盤(pán)上,使得每一個(gè)皇后都無(wú)法攻擊到其他皇后,N皇后問(wèn)題是一個(gè)典型的約束求解問(wèn)題,利用遞歸機(jī)制,可以很快的得到結(jié)果,本文將詳細(xì)介紹,需要了解的朋友可以參考下2012-11-11Spring Boot實(shí)現(xiàn)圖片上傳功能
這篇文章主要為大家詳細(xì)介紹了Spring Boot實(shí)現(xiàn)圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Windows系統(tǒng)中Java調(diào)用cmd命令及執(zhí)行exe程序的方法
這篇文章主要介紹了Windows系統(tǒng)中Java調(diào)用cmd命令及執(zhí)行exe程序的方法,主要用到了IOException類(lèi),需要的朋友可以參考下2016-03-03舉例講解Java中數(shù)組和字符串類(lèi)型的使用方法
這篇文章主要介紹了舉例講解Java中數(shù)組和字符串類(lèi)型的使用方法,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09