Maven

現(xiàn)在的項目中 Maven 隨處可見,面試的時候七芭,經(jīng)常會被問一些項目中 Maven 的問題,但是平時 Maven 項目一般不會出什么問題照卦,可能你不太注意式矫,以下7個問題,一般說出來并掌握窄瘟,至少可以證明你 Maven 用的熟練度還可以衷佃。

Maven的倉庫管理、依賴管理蹄葱、繼承和聚合等特性為項目的構建提供了一整套完善的解決方案,如果你搞不懂Maven锄列,那么一個多模塊的項目足以讓你頭疼图云,依賴沖突就會讓你不知所措,甚至搞不清楚項目是如何運行起來的...

回想一下邻邮,當你新到一家公司竣况,安裝完JDK后就會安裝配置Maven,很大可能性你需要修改settings.xml文件筒严,比如你會修改本地倉庫地址路徑丹泉,比如你很可能會copy一段配置到你的settings.xml中(很可能就是私服的一些配置)。接下來鸭蛙,你會到IDEA或者Eclipse中進行Maven插件配置摹恨,然后你就可以在工程中的pom.xml里面開始添加標簽來管理jar包,在Maven規(guī)范的目錄結(jié)構下進行編寫代碼娶视,最后你會通過插件的方式來進行測試晒哄、打包(jar or war)、部署肪获、運行寝凌。

上面描述了對Maven的一些使用方式,下面我們進行一些思考:

1孝赫、本地倉庫较木?Maven到底有哪些倉庫?它們什么關系青柄?

Maven倉庫:

圖片

本地倉庫路徑配置:

圖片

你要jar包伐债,不可能每次都要聯(lián)網(wǎng)去下載吧,多費勁刹前,所以本地倉庫就是相當于加了一層jar包緩存泳赋,先到這里來查。如果這里查不到喇喉,那么就去私服上找祖今,如果私服也找不到,那么去中央倉庫去找,找到jar后千诬,會把jar的信息同步到私服和本地倉庫中耍目。

私服,就是公司內(nèi)部局域網(wǎng)的一臺服務器而已徐绑,你想一下邪驮,當你的工程Project-A依賴別人的Project-B的接口,怎么做呢傲茄?沒有Maven的時候毅访,當然是copy Project-B jar到你的本地lib中引入,那么Maven的方式盘榨,很顯然需要其他人把Project-B deploy到私服倉庫中供你使用喻粹。因此私服中存儲了本公司的內(nèi)部專用的jar!不僅如此草巡,私服還充當了中央倉庫的鏡像守呜,說白了就是一個代理!

中央倉庫:該倉庫存儲了互聯(lián)網(wǎng)上的jar山憨,由Maven團隊來維護查乒,地址是:http://repo1.maven.org/maven2/。

2郁竟、關于 <dependency>的使用

依賴管理:

圖片

圖片

其實這個標簽揭示了jar的查找坐標:groupId玛迄、artifactId、version枪孩。

一般而言憔晒,我們可以到私服上輸入artifactId進行搜索,或者到http://search.maven.org/蔑舞、http://mvnrepository.com/上進行查找確定坐標拒担。

version分為開發(fā)版本(Snapshot)和發(fā)布版本(Release),那么為什么要分呢攻询?

在實際開發(fā)中从撼,我們經(jīng)常遇到這樣的場景,比如A服務依賴于B服務钧栖,A和B同時開發(fā)低零,B在開發(fā)中發(fā)現(xiàn)了BUG,修改后拯杠,將版本由1.0升級為2.0掏婶,那么A必須也跟著在POM.XML中進行版本升級。過了幾天后潭陪,B又發(fā)現(xiàn)了問題雄妥,進行修改后升級版本發(fā)布最蕾,然后通知A進行升級...可以說這是開發(fā)過程中的版本不穩(wěn)定導致了這樣的問題。

Maven老厌,已經(jīng)替我們想好了解決方案瘟则,就是使用Snapshot版本,在開發(fā)過程中B發(fā)布的版本標志為Snapshot版本枝秤,A進行依賴的時候選擇Snapshot版本醋拧,那么每次B發(fā)布的話,會在私服倉庫中淀弹,形成帶有時間戳的Snapshot版本丹壕,而A構建的時候會自動下載B最新時間戳的Snapshot版本!

3垦页、既然Maven進行了依賴管理雀费,為什么還會出現(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,很可能在運行階段出現(xiàn)類(ClassNotFoundException)痊末、方法(NoSuchMethodError)找不到的錯誤(因為B使用的是高版本的C)蚕苇!

這里其實涉及到了2個概念:依賴傳遞(transitive)、Maven的最近依賴策略凿叠。

依賴傳遞:如果A依賴B涩笤,B依賴C嚼吞,那么引入A,意味著B和C都會被引入辆它。

Maven的最近依賴策略:如果一個項目依賴相同的groupId誊薄、artifactId的多個版本,那么在依賴樹(mvn dependency:tree)中離項目最近的那個版本將會被使用锰茉。(從這里可以看出Maven是不是有點小問題呢呢蔫?能不能選擇高版本的進行依賴么?據(jù)了解飒筑,Gradle就是version+策略)

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

想法1:要使用哪個版本协屡,我們是清楚的俏脊,那么能不能不管如何依賴傳遞,都可以進行版本鎖定呢肤晓?

使用 <dependencyManagement> 這種主要用于子模塊的版本一致性中

想法2:在依賴傳遞中爷贫,能不能去掉我們不想依賴的?

使用 <exclusions>在實際中我們可以在IDEA中直接利用插件幫助我們生成

想法3:既然是最近依賴策略补憾,那么我們就直接使用顯式依賴指定版本漫萄,那不就是最靠近項目的么?

使用 <dependency>

4盈匾、引入依賴的最佳實踐腾务,提前發(fā)現(xiàn)問題!

在工程中削饵,我們避免不了需要加一些依賴岩瘦,也許加了依賴后運行時才發(fā)現(xiàn)存在依賴沖突在去解決,似乎有點晚窿撬!那么能不能提前發(fā)現(xiàn)問題呢启昧?

如果我們新加入一個依賴的話,那么先通過mvn dependency:tree命令形成依賴樹尤仍,看看我們新加入的依賴箫津,是否存在傳遞依賴,傳遞依賴中是否和依賴樹中的版本存在沖突宰啦,如果存在多個版本沖突苏遥,利用上文的方式進行解決!

5赡模、Maven規(guī)范化目錄結(jié)構

圖片

這里需要注意2點:

1田炭、src/main下內(nèi)容最終會打包到Jar/War中,而src/test下是測試內(nèi)容漓柑,并不會打包進去教硫。

2叨吮、src/main/resources中的資源文件會COPY至目標目錄,這是Maven的默認生命周期中的一個規(guī)定動作瞬矩。(想一想茶鉴,hibernate/mybatis的映射XML需要放入resources下,而不能在放在其他地方了)

6景用、Maven的生命周期

Maven生命周期:

圖片

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

實際上伞插,我們最常用的就是這么幾個:

1割粮、clean:有問題,多清理媚污!

2舀瓢、package:打成Jar or War包,會自動進行clean+compile

3耗美、install:將本地工程Jar上傳到本地倉庫

4京髓、deploy:上傳到私服

7、關于scope依賴范圍

既然商架,Maven的生命周期存在編譯朵锣、測試、運行這些過程甸私,那么顯然有些依賴只用于測試,比如junit飞傀;有些依賴編譯用不到皇型,只有運行的時候才能用到,比如mysql的驅(qū)動包在編譯期就用不到(編譯期用的是JDBC接口)砸烦,而是在運行時用到的弃鸦;還有些依賴,編譯期要用到幢痘,而運行期不需要提供唬格,因為有些容器已經(jīng)提供了,比如servlet-api在tomcat中已經(jīng)提供了颜说,我們只需要的是編譯期提供而已购岗。

總結(jié)來說:

1、compile:默認的scope门粪,運行期有效喊积,需要打入包中。

2玄妈、provided:編譯期有效乾吻,運行期不需要提供髓梅,不會打入包中。

3绎签、runtime:編譯不需要枯饿,在運行期有效,需要導入包中诡必。(接口與實現(xiàn)分離)

4奢方、test:測試需要,不會打入包中擒权。

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

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愉老,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子剖效,更是在濱河造成了極大的恐慌嫉入,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件璧尸,死亡現(xiàn)場離奇詭異咒林,居然都是意外死亡,警方通過查閱死者的電腦和手機爷光,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門垫竞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛀序,你說我怎么就攤上這事欢瞪。” “怎么了徐裸?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵遣鼓,是天一觀的道長。 經(jīng)常有香客問我重贺,道長骑祟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任气笙,我火速辦了婚禮次企,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘健民。我一直安慰自己抒巢,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布秉犹。 她就那樣靜靜地躺著蛉谜,像睡著了一般稚晚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上型诚,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天客燕,我揣著相機與錄音,去河邊找鬼狰贯。 笑死也搓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的涵紊。 我是一名探鬼主播傍妒,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼摸柄!你這毒婦竟也來了颤练?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驱负,失蹤者是張志新(化名)和其女友劉穎嗦玖,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跃脊,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡宇挫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酪术。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片器瘪。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绘雁,靈堂內(nèi)的尸體忽然破棺而出娱局,到底是詐尸還是另有隱情,我是刑警寧澤咧七,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站任斋,受9級特大地震影響继阻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜废酷,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一瘟檩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澈蟆,春花似錦墨辛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奏赘。三九已至,卻和暖如春太惠,著一層夾襖步出監(jiān)牢的瞬間磨淌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工凿渊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梁只,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓埃脏,卻偏偏與公主長得像搪锣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子彩掐,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

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