搞懂這7個Maven問題涮总,帶你吊打面試官胸囱!

在如今的互聯(lián)網(wǎng)項(xiàng)目開發(fā)當(dāng)中,特別是Java領(lǐng)域瀑梗,可以說Maven隨處可見烹笔。Maven的倉庫管理裳扯、依賴管理、繼承和聚合等特性為項(xiàng)目的構(gòu)建提供了一整套完善的解決方案谤职,可以說如果你搞不懂Maven饰豺,那么一個多模塊的項(xiàng)目足以讓你頭疼,依賴沖突就會讓你不知所措允蜈,甚至搞不清楚項(xiàng)目是如何運(yùn)行起來的....

OK冤吨,博主就曾經(jīng)被Maven“傷害”過,那么該專題的目的就是:徹底搞定Maven饶套!
回想一下漩蟆,當(dāng)你新到一家公司,安裝完JDK后就會安裝配置Maven(MAVEN_HOME妓蛮、path)怠李,很大可能性你需要修改settings.xml文件,比如你會修改本地倉庫地址路徑蛤克,比如你很可能會copy一段配置到你的settings.xml中(很可能就是私服的一些配置)捺癞。

接下來,你會到IDEA或者Eclipse中進(jìn)行Maven插件配置构挤,然后你就可以在工程中的pom.xml里面開始添加<dependency>標(biāo)簽來管理jar包翘簇,在Maven規(guī)范的目錄結(jié)構(gòu)下進(jìn)行編寫代碼,最后你會通過插件的方式來進(jìn)行測試儿倒、打包(jar or war)版保、部署、運(yùn)行夫否。

上面描述了我們對Maven的一些使用方式彻犁,下面我們進(jìn)行一些思考:

  1. 本地倉庫?Maven到底有哪些倉庫凰慈?它們什么關(guān)系汞幢?

Maven倉庫
本地倉庫路徑配置

你要jar包,不可能每次都要聯(lián)網(wǎng)去下載吧微谓,多費(fèi)勁森篷,所以本地倉庫就是相當(dāng)于加了一層jar包緩存,先到這里來查仲智。如果這里查不到,那么就去私服上找前联,如果私服也找不到似嗤,那么去中央倉庫去找,找到j(luò)ar后乘粒,會把jar的信息同步到私服和本地倉庫中顽馋。

私服幌羞,就是公司內(nèi)部局域網(wǎng)的一臺服務(wù)器而已熊痴,你想一下果善,當(dāng)你的工程Project-A依賴別人的Project-B的接口,怎么做呢鄙煤?沒有Maven的時候,當(dāng)然是copy Project-B jar到你的本地lib中引入茶袒,那么Maven的方式,很顯然需要其他人把Project-B deploy到私服倉庫中供你使用。因此私服中存儲了本公司的內(nèi)部專用的jar!不僅如此存崖,私服還充當(dāng)了中央倉庫的鏡像来惧,說白了就是一個代理钠至!如何創(chuàng)建私服棉钧,可以關(guān)注Java技術(shù)棧微信公眾號宪卿,回復(fù):maven休溶,即可獲取禾进。

中央倉庫:該倉庫存儲了互聯(lián)網(wǎng)上的jar泻云,由Maven團(tuán)隊(duì)來維護(hù)艇拍,地址是:http://repo1.maven.org/maven2/

  1. 關(guān)于<dependency>的使用
    依賴管理
    其實(shí)這個標(biāo)簽揭示了jar的查找坐標(biāo):groupId宠纯、artifactId卸夕、version。

一般而言婆瓜,我們可以到私服上輸入artifactId進(jìn)行搜索快集,或者到http://search.maven.org/贡羔、http://mvnrepository.com/上進(jìn)行查找確定坐標(biāo)。

version分為開發(fā)版本(Snapshot)和發(fā)布版本(Release)个初,那么為什么要分呢乖寒?

在實(shí)際開發(fā)中,我們經(jīng)常遇到這樣的場景院溺,比如A服務(wù)依賴于B服務(wù)楣嘁,A和B同時開發(fā),B在開發(fā)中發(fā)現(xiàn)了BUG珍逸,修改后逐虚,將版本由1.0升級為2.0,那么A必須也跟著在POM.XML中進(jìn)行版本升級谆膳。過了幾天后叭爱,B又發(fā)現(xiàn)了問題,進(jìn)行修改后升級版本發(fā)布漱病,然后通知A進(jìn)行升級...可以說這是開發(fā)過程中的版本不穩(wěn)定導(dǎo)致了這樣的問題买雾。

Maven,已經(jīng)替我們想好了解決方案缨称,就是使用Snapshot版本凝果,在開發(fā)過程中B發(fā)布的版本標(biāo)志為Snapshot版本祝迂,A進(jìn)行依賴的時候選擇Snapshot版本睦尽,那么每次B發(fā)布的話,會在私服倉庫中型雳,形成帶有時間戳的Snapshot版本当凡,而A構(gòu)建的時候會自動下載B最新時間戳的Snapshot版本!

  1. 既然Maven進(jìn)行了依賴管理纠俭,為什么還會出現(xiàn)依賴沖突沿量?處理依賴沖突的手段是?
    依賴的版本冤荆?

首先來說朴则,對于Maven而言,同一個groupId同一個artifactId下钓简,只能使用一個version乌妒!

根據(jù)上圖的依賴順序,將使用1.2版本的jar外邓。

現(xiàn)在撤蚊,我們可以思考下了,比如工程中需要引入A损话、B侦啸,而A依賴1.0版本的C槽唾,B依賴2.0版本的C,那么問題來了光涂,C使用的版本將由引入A庞萍、B的順序而定?這顯然不靠譜顶捷!如果A的依賴寫在B的依賴后面挂绰,將意味著最后引入的是1.0版本的C,很可能在運(yùn)行階段出現(xiàn)類(ClassNotFoundException)服赎、方法(NoSuchMethodError)找不到的錯誤(因?yàn)锽使用的是高版本的C)葵蒂!

這里其實(shí)涉及到了2個概念:依賴傳遞(transitive)、Maven的最近依賴策略重虑。
依賴傳遞:如果A依賴B践付,B依賴C,那么引入A缺厉,意味著B和C都會被引入永高。

Maven的最近依賴策略:如果一個項(xiàng)目依賴相同的groupId、artifactId的多個版本提针,那么在依賴樹(mvn dependency:tree)中離項(xiàng)目最近的那個版本將會被使用命爬。(從這里可以看出Maven是不是有點(diǎn)小問題呢?能不能選擇高版本的進(jìn)行依賴么辐脖?據(jù)了解饲宛,Gradle就是version+策略)

現(xiàn)在,我們可以想想如何處理依賴沖突呢嗜价?

想法1:要使用哪個版本艇抠,我們是清楚的,那么能不能不管如何依賴傳遞久锥,都可以進(jìn)行版本鎖定呢家淤?

使用<dependencyManagement> [這種主要用于子模塊的版本一致性中]
想法2:在依賴傳遞中,能不能去掉我們不想依賴的瑟由?

使用<exclusions> [在實(shí)際中我們可以在IDEA中直接利用插件幫助我們生成]
想法3:既然是最近依賴策略絮重,那么我們就直接使用顯式依賴指定版本,那不就是最靠近項(xiàng)目的么歹苦?Maven繼承與聚合青伤,這個你需要掌握。

使用<dependency>

  1. 引入依賴的最佳實(shí)踐暂氯,提前發(fā)現(xiàn)問題潮模!

在工程中,我們避免不了需要加一些依賴痴施,也許加了依賴后運(yùn)行時才發(fā)現(xiàn)存在依賴沖突在去解決擎厢,似乎有點(diǎn)晚究流!那么能不能提前發(fā)現(xiàn)問題呢?

如果我們新加入一個依賴的話动遭,那么先通過mvn dependency:tree命令形成依賴樹芬探,看看我們新加入的依賴,是否存在傳遞依賴厘惦,傳遞依賴中是否和依賴樹中的版本存在沖突偷仿,如果存在多個版本沖突,利用上文的方式進(jìn)行解決宵蕉!

  1. Maven規(guī)范化目錄結(jié)構(gòu)
    簡單Java工程目錄結(jié)構(gòu)

這里需要注意2點(diǎn):

第一:src/main下內(nèi)容最終會打包到Jar/War中酝静,而src/test下是測試內(nèi)容,并不會打包進(jìn)去羡玛。

第二:src/main/resources中的資源文件會COPY至目標(biāo)目錄别智,這是Maven的默認(rèn)生命周期中的一個規(guī)定動作。(想一想稼稿,hibernate/mybatis的映射XML需要放入resources下薄榛,而不能在放在其他地方了)

  1. Maven的生命周期
    Maven生命周期

我們只需要注意一點(diǎn):執(zhí)行后面的命令時,前面的命令自動得到執(zhí)行让歼。

實(shí)際上敞恋,我們最常用的就是這么幾個:

clean:有問題,多清理谋右!

package:打成Jar or War包硬猫,會自動進(jìn)行clean+compile

install:將本地工程Jar上傳到本地倉庫

deploy:上傳到私服

  1. 關(guān)于scope依賴范圍

既然,Maven的生命周期存在編譯倚评、測試浦徊、運(yùn)行這些過程馏予,那么顯然有些依賴只用于測試天梧,比如junit;有些依賴編譯用不到霞丧,只有運(yùn)行的時候才能用到呢岗,比如mysql的驅(qū)動包在編譯期就用不到(編譯期用的是JDBC接口),而是在運(yùn)行時用到的蛹尝;還有些依賴后豫,編譯期要用到,而運(yùn)行期不需要提供突那,因?yàn)橛行┤萜饕呀?jīng)提供了剔交,比如servlet-api在tomcat中已經(jīng)提供了也拜,我們只需要的是編譯期提供而已。

總結(jié)來說:

compile:默認(rèn)的scope焰扳,運(yùn)行期有效,需要打入包中寂汇。

provided:編譯期有效,運(yùn)行期不需要提供,不會打入包中壹店。

runtime:編譯不需要,在運(yùn)行期有效芝加,需要導(dǎo)入包中硅卢。(接口與實(shí)現(xiàn)分離)
test:測試需要,不會打入包中藏杖。

system:非本地倉庫引入将塑、存在系統(tǒng)的某個路徑下的jar。(一般不使用)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蝌麸,一起剝皮案震驚了整個濱河市抬旺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祥楣,老刑警劉巖开财,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異误褪,居然都是意外死亡责鳍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門兽间,熙熙樓的掌柜王于貴愁眉苦臉地迎上來历葛,“玉大人,你說我怎么就攤上這事嘀略⌒羧埽” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵帜羊,是天一觀的道長咒程。 經(jīng)常有香客問我,道長讼育,這世上最難降的妖魔是什么帐姻? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮奶段,結(jié)果婚禮上饥瓷,老公的妹妹穿的比我還像新娘。我一直安慰自己痹籍,他們只是感情好呢铆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蹲缠,像睡著了一般棺克。 火紅的嫁衣襯著肌膚如雪鳖宾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天逆航,我揣著相機(jī)與錄音鼎文,去河邊找鬼。 笑死因俐,一個胖子當(dāng)著我的面吹牛拇惋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抹剩,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼撑帖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澳眷?” 一聲冷哼從身側(cè)響起胡嘿,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钳踊,沒想到半個月后衷敌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拓瞪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年缴罗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祭埂。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡面氓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛆橡,到底是詐尸還是另有隱情舌界,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布泰演,位于F島的核電站呻拌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粥血。R本人自食惡果不足惜柏锄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一酿箭、第九天 我趴在偏房一處隱蔽的房頂上張望复亏。 院中可真熱鬧,春花似錦缭嫡、人聲如沸缔御。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耕突。三九已至笤成,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間眷茁,已是汗流浹背炕泳。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留上祈,地道東北人培遵。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像登刺,于是被迫代替她去往敵國和親籽腕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容