Maven中optional標籤詳解(轉)

原文:https://blog.csdn.net/weixin_43888891/article/details/130510971

作者:

來源:CSDN
 

一、前言

<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.18</version>
  <optional>true</optional>
</dependency>

optional表示是否會傳遞依賴,有兩個可填值(假如不聲明optional標籤,默認就是false):

false: 傳遞依賴
true:不傳遞依賴
舉例:A引用了B的依賴,而B又引用了C依賴。

假如B引用C依賴的時候沒有設置optional,那麼A是可以使用C依賴的。
假如B引用C依賴的時候將optional標籤設置爲了true,那麼在A當中就無法使用C依賴相關的方法,並且A調用B依賴的方法,而B依賴方法使用到了C,這時候會報找不到C依賴下的類,因爲C不參與A的打包。

二、依賴傳遞代碼演示

(1)如下是一個父子聚合工程,不設置optional的情況:

打成jar包後,我們可以將jar解壓,解壓後在BOOT-INF的lib下存放着所能使用的依賴jar包,在這裏可以看到hutool

 

(2)設置optional爲true的情況:

沒有那也就意味着我再download工程不能訪問hutool的類了,想要訪問只能在當前項目再次引用了。

(3)我有點好奇,既然這裏看不到那麼他究竟會參與打包嗎?假如不參與打包,我們download工程調用common中的方法,然後common中的方法又使用了hutool工具類,那能否訪問成功?接下來我們來一點一點的印證!

設置爲true的時候是否會參與download工程的打包?

答:他是不會參與download的打包的,打成jar包後,我們可以將jar解壓,解壓後在BOOT-INF的lib下存放着所能使用的依賴jar包。

 假如不參與打包,我們download工程調用common中的方法,然後common中的方法又使用了hutool工具類,那能否訪問成功?

答:不能訪問成功,直接會報找不到hutool的類

我解壓common包發現連BOOT-INF都沒有,並不是只有common的jar包解壓沒有,而是所有的都沒有。

我一直以爲common包引用了hutool,那麼解壓common包就應該在BOOT-INF下的jar中看到hutool.jar,其實不是的,maven打包會將所有依賴關係全部放到當前項目的BOOT-INF/jar目錄下

 爲此我專門在common當中寫了一個方法,然後使用到了hutool當中的類。

 然後我又在download工程下寫了一個接口,讓這個接口訪問common包下test方法。

 緊接着啓動項目,啓動download項目並沒有異常,只要訪問common包當中方法帶有hutool相關的都報異常,說找不到hutool的包。因爲我們剛剛也看過了,確實是沒有這個jar包。

 

從而也證明了,不管是當前項目引用的,還是間接引用的,jar包都存放在BOOT-INF下/jar目錄下,只要這下面沒有jar,那當前項目就不能用。

三、爲啥common的jar包下沒有BOOT-INF呢?

在download下的BOOT-INF/lib下的common包解壓後沒有BOOT-INF我可以理解,因爲所有的jar包都沒有。但是爲什麼target當中的jar包解壓後也沒有,而download卻有。他兩個唯一的區別就是,一個是有main函數的web工程,一個是連main方法都沒有的而且也沒有打包插件。

 我的父工程繼承了spring-boot-starter-parent

 而spring-boot-starter-parent當中對打包插件做了如下配置,也就意味着子工程一旦聲明該插件就會遵循如下配置:

於是我在common包下添加了打包插件。注意使用打包插件意味着打出來的jar是一個可以直接執行的jar,因此必須要聲明main函數,否則會打包異常的。

 並且新增了一個主函數

 於是再次打包,這時候會發現jar包大小已經發生了變化。解壓後會發現他已經存在BOOT-INF了。

 但是詭異的一幕發生了,download引入了common包,並且download調用了common包下的方法,直接就mvn install 不通過了。說在倉庫找不到包。

 但是在倉庫當中實際上是存在這個包的。那也就是證明項目不能引用可執行jar。

 於是我又把common的打包插件給去掉之後mvn install可以成功了。因此也證明了假如我們要封裝自己的jar,一定不要使用打包插件。一旦使用插件就會變成了可執行jar,可執行jar是不可以被別的項目所引用的。

四、是否會影響父子工程之間的依賴繼承呢?

假如我在聚合工程的父pom依賴當中使用optional爲true,那子工程會繼承嗎?接下來進行演示。

 

 

 注:在父工程設置optional爲true,並不會影響子工程繼承該依賴。

 

五、總結

將依賴設置爲true不僅代表着依賴不會傳遞,就連打包的時候都不會將該jar打包進去,一旦使用到調用該jar包的方法就會異常。
在父工程設置optional爲true,並不會影響子工程繼承該依賴。
不管是當前項目引用的,還是間接引用的,所有依賴jar包都存放在jar解壓後的BOOT-INF下/jar目錄下,只要這下面沒有jar,那當前項目就不能用。
什麼時候將optional設置爲true?

就拿hutool工具類來說,如下圖:你想用他的某些工具類,他還讓你引用一些第三方的依賴,爲什麼他不直接引用到自己的項目?

實際上hutool他肯定是引用了的,如果不引用他的項目可能連編譯都編譯不過,更別提打包給我們用了,他是將這個依賴設置爲了true,假如誰用到了這塊的功能,誰自己引入這個依賴。這樣可以規避掉一些沒有用到這塊功能但是卻引入了沒有用的jar包。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章