Maven 的這 7 個問題你思考過沒有豌蟋?

來源:http://www.reibang.com/p/20b39ab6a88c

在如今的互聯(lián)網(wǎng)項目開發(fā)當中速和,特別是Java領域,可以說Maven隨處可見剥汤。Maven的倉庫管理颠放、依賴管理、繼承和聚合等特性為項目的構(gòu)建提供了一整套完善的解決方案吭敢,可以說如果你搞不懂Maven碰凶,那么一個多模塊的項目足以讓你頭疼,依賴沖突就會讓你不知所措鹿驼,甚至搞不清楚項目是如何運行起來的.....OK欲低,博主就曾經(jīng)被Maven“傷害”過,那么該專題的目的就是:徹底搞定Maven畜晰!

回想一下砾莱,當你新到一家公司,安裝完JDK后就會安裝配置Maven(MAVEN_HOME凄鼻、path)腊瑟,很大可能性你需要修改settings.xml文件,比如你會修改本地倉庫地址路徑块蚌,比如你很可能會copy一段配置到你的settings.xml中(很可能就是私服的一些配置)闰非。接下來,你會到IDEA或者Eclipse中進行Maven插件配置峭范,然后你就可以在工程中的pom.xml里面開始添加<dependency>標簽來管理jar包财松,在Maven規(guī)范的目錄結(jié)構(gòu)下進行編寫代碼,最后你會通過插件的方式來進行測試纱控、打包(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構(gòu)建的時候會自動下載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é)構(gòu)

簡單Java工程目錄結(jié)構(gòu)

這里需要注意2點:

第一:src/main下內(nèi)容最終會打包到Jar/War中猖腕,而src/test下是測試內(nèi)容拆祈,并不會打包進去。

第二:src/main/resources中的資源文件會COPY至目標目錄倘感,這是Maven的默認生命周期中的一個規(guī)定動作放坏。(想一想,hibernate/mybatis的映射XML需要放入resources下老玛,而不能在放在其他地方了)

6. Maven的生命周期

Maven生命周期

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

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

clean:有問題麸粮,多清理!

package:打成Jar or War包镜廉,會自動進行clean+compile

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

deploy:上傳到私服

7. 關于scope依賴范圍

既然弄诲,Maven的生命周期存在編譯、測試娇唯、運行這些過程齐遵,那么顯然有些依賴只用于測試,比如junit塔插;有些依賴編譯用不到洛搀,只有運行的時候才能用到,比如mysql的驅(qū)動包在編譯期就用不到(編譯期用的是JDBC接口)佑淀,而是在運行時用到的;還有些依賴彰檬,編譯期要用到伸刃,而運行期不需要提供,因為有些容器已經(jīng)提供了逢倍,比如servlet-api在tomcat中已經(jīng)提供了捧颅,我們只需要的是編譯期提供而已。

總結(jié)來說:

compile:默認的scope较雕,運行期有效碉哑,需要打入包中挚币。

provided:編譯期有效,運行期不需要提供扣典,不會打入包中妆毕。

runtime:編譯不需要,在運行期有效贮尖,需要導入包中笛粘。(接口與實現(xiàn)分離)

test:測試需要,不會打入包中湿硝。

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

Maven虐我千百遍关斜,我待Maven如初戀示括!

如果學到了東西,歡迎點贊痢畜、轉(zhuǎn)發(fā)垛膝!

擴展閱讀

Maven 結(jié)合 IDEA 入門實踐

maven常用命令集合(收藏大全)

Maven學習總結(jié)-構(gòu)建項目

Git常用命令速查表(收藏大全)

Vim 命令、操作裁着、快捷鍵(收藏大全)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末繁涂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子二驰,更是在濱河造成了極大的恐慌扔罪,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桶雀,死亡現(xiàn)場離奇詭異矿酵,居然都是意外死亡,警方通過查閱死者的電腦和手機矗积,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門全肮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棘捣,你說我怎么就攤上這事辜腺。” “怎么了乍恐?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵评疗,是天一觀的道長。 經(jīng)常有香客問我茵烈,道長百匆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任呜投,我火速辦了婚禮加匈,結(jié)果婚禮上存璃,老公的妹妹穿的比我還像新娘。我一直安慰自己雕拼,他們只是感情好纵东,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悲没,像睡著了一般篮迎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上示姿,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天甜橱,我揣著相機與錄音,去河邊找鬼栈戳。 笑死岂傲,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的子檀。 我是一名探鬼主播镊掖,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼褂痰!你這毒婦竟也來了亩进?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤缩歪,失蹤者是張志新(化名)和其女友劉穎归薛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匪蝙,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡主籍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逛球。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片千元。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖颤绕,靈堂內(nèi)的尸體忽然破棺而出幸海,到底是詐尸還是另有隱情,我是刑警寧澤奥务,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布涕烧,位于F島的核電站,受9級特大地震影響汗洒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜父款,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一溢谤、第九天 我趴在偏房一處隱蔽的房頂上張望瞻凤。 院中可真熱鬧,春花似錦世杀、人聲如沸阀参。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛛壳。三九已至,卻和暖如春所刀,著一層夾襖步出監(jiān)牢的瞬間衙荐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工浮创, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忧吟,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓斩披,卻偏偏與公主長得像溜族,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子垦沉,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

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

  • |-1-更新內(nèi)容[6.從倉庫解析依賴的機制(重要)] 1Maven倉庫作用 倉庫用來存儲所有項目使用到構(gòu)件煌抒,在ma...
    zlcook閱讀 6,054評論 0 25
  • Maven的基本了解 什么是Maven? Maven就是Apache下的一個開源項目厕倍。它是用純java開發(fā)的寡壮。是一...
    Bcome閱讀 2,820評論 0 7
  • 在 Maven 的術語中,倉庫是一個位置(place)绑青。Maven 倉庫是項目中依賴的第三方庫诬像,這個庫所在的位置叫...
    41uLove閱讀 6,971評論 2 3
  • 逅弈 轉(zhuǎn)載請注明原創(chuàng)出處,謝謝闸婴! 以前的日子 以前我們寫代碼時坏挠,jar包都默認放在一個叫 /lib 的目錄下,然后...
    逅弈閱讀 2,885評論 3 45
  • 嗨~小伙伴們大家好~ (請自動腦補名偵探柯南的片頭曲) 不知道小伙伴們對于品嘗陌生城市的美食是不是特別激動呢邪乍?二總...
    叁味食堂閱讀 658評論 0 0