詳解Maven optional關(guān)鍵字透徹圖解
寫在前面
本來想寫一篇「如何自定義Spring Boot Starter」,但是為了更好理解 Starter 的一些設(shè)計(jì)理念和其中的關(guān)鍵點(diǎn),所以提前將一些細(xì)節(jié)內(nèi)容單獨(dú)提取出來講解說明
在 Maven pom.xml 中,你經(jīng)常會看到依賴項(xiàng)中有類似下面的代碼:
<dependency> <groupId>sample.ProjectA</groupId> <artifactId>Project-A</artifactId> <version>1.0</version> <scope>compile</scope> <optional>true</optional> </dependency>
這里的 <optional>true</optional> 是什么意思呢?
optional 關(guān)鍵字的奧秘
老規(guī)矩,畫個圖說明問題:

由于 project C 使用到了兩個來自 project A 的類 (OptionalFeatureAClass) 和 project B 的類 (OptionalFeatureBClass). 如果 project C 沒有依賴 packageA 和 packageB,那么編譯將會失敗。
project D 依賴 project C,但是對于 project D 來說,類 (OptionalFeatureAClass) 和類 (OptionalFeatureBClass) 是可選的特性,所以為了讓最終的 war/ejb package 不包含不必要的依賴,使用<optional> 聲明當(dāng)前依賴是可選的, 默認(rèn)情況下也不會被其他項(xiàng)目繼承(好比 Java 中的 final 類,不能被其他類繼承一樣)
如果 project D 確實(shí)需要用到 project C 中的 OptionalFeatureAClass 怎么辦呢?那我們就需要在 project D 的 pom.xml 中顯式的添加聲明 project A 依賴,繼續(xù)看下圖:

Project D 需要用到 Project A 的 OptionalFeatureAClass,那么需要在 Project D 的 pom.xml 文件中顯式的添加對 Project A 的依賴
到這也就很好理解為什么 Maven 為什么要設(shè)計(jì) optional 關(guān)鍵字了,假設(shè)一個關(guān)于數(shù)據(jù)庫持久化的項(xiàng)目(Project C), 為了適配更多類型的數(shù)據(jù)庫持久化設(shè)計(jì),比如 Mysql 持久化設(shè)計(jì)(Project A) 和 Oracle 持久化設(shè)計(jì)(Project B),當(dāng)我們的項(xiàng)目(Project D) 要用的 Project C 的持久化設(shè)計(jì),不可能既引入 mysql 驅(qū)動又引入 oracle 驅(qū)動吧,所以我們要顯式的指定一個,就是這個道理了
實(shí)際案例
在 spring-boot-actuator pom.xml 文件中,有超過 20 個依賴是 optional

因?yàn)?Spring Boot 不可能將沒必要的依賴也打包到你最終的 jar package 中,所以用到 spring boot actuator 的項(xiàng)目最終生成的 jar package 中不會包含這 20 多個依賴 jar,如果你要用到哪一個,顯式的加入到你的項(xiàng)目就好了
在接下來的文章,自定義 Spring Boot Starter 也是這個策略,因?yàn)?starter 是包含特定功能為其他項(xiàng)目服務(wù)用的,類似本文的 Project C 的角色了,到這里你理解 optional 的奧秘了嗎?
反向應(yīng)用
如果 Project C 引入的依賴沒有加 <optional>true</optional>,Project D 又需要依賴 Project C,但只用到 Project A 的類怎么辦呢?Maven 也是有解決辦法的,使用 exclusion 關(guān)鍵字,不多說,上一段代碼就懂了:
<dependencies>
<dependency>
<groupId>top.dayarch.demo</groupId>
<artifactId>Project-C</artifactId>
<exclusions>
<exclusion>
<groupId>top.dayarch.demo</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
總結(jié)
到這里,在你今后設(shè)計(jì)功能性依賴時,你應(yīng)該明白怎樣設(shè)計(jì)依賴關(guān)系了, 我這里推薦使用 optional 的形式,簡單來說,你設(shè)計(jì)的依賴什么菜都有,想吃什么菜自己 "抱蔡明" 就好,接下來我們就模擬官方標(biāo)準(zhǔn)創(chuàng)建自定義的 starter...... 博客 訪問恢復(fù)正常,歡迎交流
靈魂追問
- 有很多童鞋項(xiàng)目組用的構(gòu)建工具時 Gradle,你知道 Gradle 中是怎樣表示的嗎?
- 自定義 starter,你知道官方標(biāo)準(zhǔn) starter 的結(jié)構(gòu)是什么樣的嗎?
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于java語言實(shí)現(xiàn)快遞系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于java語言實(shí)現(xiàn)快遞系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
SpringBoot啟動訪問localhost:8080報(bào)錯404的解決操作
這篇文章主要介紹了SpringBoot啟動訪問localhost:8080報(bào)錯404的解決操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
java正則表達(dá)式實(shí)現(xiàn)提取需要的字符并放入數(shù)組【ArrayList數(shù)組去重復(fù)功能】
這篇文章主要介紹了java正則表達(dá)式實(shí)現(xiàn)提取需要的字符并放入數(shù)組,即基于正則的ArrayList數(shù)組去重復(fù)功能,具有一定參考借鑒價值,需要的朋友可以參考下2017-01-01
Java實(shí)現(xiàn)冒泡排序與雙向冒泡排序算法的代碼示例
這篇文章主要介紹了Java實(shí)現(xiàn)冒泡排序與雙向冒泡排序算法的代碼示例,值得一提的是所謂的雙向冒泡排序并不比普通的冒泡排序效率來得高,注意相應(yīng)的時間復(fù)雜度,需要的朋友可以參考下2016-04-04
詳解Spring與Mybatis的整合方法(基于Eclipse的搭建)
這篇文章主要介紹了Spring與Mybatis的整合方法(基于Eclipse的搭建),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10

