Maven是目前JAVA開發(fā)主要使用的依賴管理構(gòu)建工具之一,但是很多人在引用依賴的時(shí)候直接引用坐標(biāo),而沒有考慮依賴的作用范圍,結(jié)果導(dǎo)致出現(xiàn)這樣和那樣的問(wèn)題。今天胖哥就來(lái)說(shuō)明一下Maven引用依賴的一個(gè)要點(diǎn)概念——作用域。
要選擇正確的scope
scope是Maven坐標(biāo)的一個(gè)關(guān)鍵字,它主要來(lái)限制依賴的作用域。它有五種類型:
Maven依賴的作用域
選擇合理的作用域,能夠避免一些依賴引用問(wèn)題。
compile
這是我們大部分情況下使用的引用作用域,它也是Maven默認(rèn)的scope值,表明該依賴從Java代碼編譯、測(cè)試以及運(yùn)行時(shí)都會(huì)參與其中。
runtime
runtime顧名思義,只參與運(yùn)行時(shí),跳過(guò)了編譯階段。當(dāng)然它打fat jar時(shí)也會(huì)像compile一樣打包。比如我們常用的數(shù)據(jù)庫(kù)驅(qū)動(dòng),你可以去看看自己Spring Boot項(xiàng)目生成器初始化數(shù)據(jù)庫(kù)驅(qū)動(dòng)依賴的是不是runtime。
provided
provided用的同學(xué)相信不會(huì)太多。它用來(lái)聲明你希望JDK和容器運(yùn)行時(shí)來(lái)提供它,你自己不引入,僅僅使用這個(gè)依賴,在一些通用規(guī)范和插件擴(kuò)展使用該選項(xiàng)比較普遍。舉個(gè)例子,servlet api你希望Servlet容器提供,但是你自己還希望去調(diào)用HttpServletRequest之類的API,你就可以用provided來(lái)聲明。
它還有一個(gè)場(chǎng)景,比如你自己開發(fā)一個(gè)針對(duì)某個(gè)類庫(kù)A的擴(kuò)展類庫(kù)B,你肯定要在擴(kuò)展類庫(kù)B中引用A。如果你不使用provided,當(dāng)你開發(fā)完擴(kuò)展類庫(kù)B,直接引用B就能使用完整的功能;如果你使用provided,你需要同時(shí)引用A和B。為什么要這樣做呢?這樣做可以讓擴(kuò)展類庫(kù)更加純粹,僅僅提供擴(kuò)展功能,而不干涉主類庫(kù)的功能,徹底的插件化。
system感覺和provided正好相反。provided是要求別人提供;而system是別人不提供自己提供, Maven不會(huì)在本地存儲(chǔ)庫(kù)中查找。使用system的大部分沒有托管在Maven中央倉(cāng)庫(kù)和私有倉(cāng)庫(kù),另外provided不會(huì)被打包,只是申明一個(gè)調(diào)用關(guān)系,system會(huì)被打包。
?
胖哥僅僅建議在測(cè)試一些三方私有jar的時(shí)候使用,如果該jar被選中的話,還是建議放入私有倉(cāng)庫(kù)。system我個(gè)人不建議在生產(chǎn)中使用。
optional
optional不是scope的一個(gè)選項(xiàng),而是一個(gè)關(guān)鍵字,它的選項(xiàng)是布爾值true和false。這里之所以要說(shuō)一說(shuō),是因?yàn)樗材芸刂埔蕾嚨淖饔糜颍徊贿^(guò)它的場(chǎng)景和上面的不一樣。它用來(lái)聲明依賴是否是可選的(optional)而不向上傳遞。
來(lái)舉一個(gè)例子,胖哥開發(fā)了一個(gè)類庫(kù),使用了lombok。但是很多開發(fā)者很反感lombok,一看胖哥的這個(gè)類庫(kù)里面用lombok他們就不用了。胖哥為了推廣,肯定要想辦法照顧這一部分人,所以就讓lombok的optional值設(shè)置為true。這樣不耽誤胖哥類庫(kù)中lombok注解的使用,也不影響使用了胖哥類庫(kù)的開發(fā)者。你可以去看看Spring Boot Starter,里面使用了大量的optional。
?
要注意和provided的區(qū)別,provided是這個(gè)庫(kù)我一定要用,但是這個(gè)庫(kù)我不提供;optional是這個(gè)庫(kù)我也用,但是我不給你用。
總結(jié)
依賴作用域在開發(fā)中一定不要忽略,選擇合理的作用域能讓你項(xiàng)目的依賴更加合理和“干凈”。看了本篇后,趕緊去看看你項(xiàng)目的依賴引用是否合理吧。