Java的包管理與Maven

前言:在Java的世界中扳缕,【包】是最基本的結構,因此包管理就是Java項目中的一件特別重要的事情。本文介紹的就是Java世界中的包管理躯舔,以及最流行的包管理工具Maven驴剔。


Java的包管理

要介紹Java的包管理,我們就要先知道什么是包:

包管理中的【包】指的是什么粥庄?

  • 首先丧失,我要知道JVM(Java Virtual Machine,即Java虛擬機)的工作原理惜互。實際上布讹,JVM的工作被設計的相當簡單:

    1. 執(zhí)行一個類的字節(jié)碼
    2. 假如這個過程中碰到了新的類,就加載它训堆,然后執(zhí)行第一個步驟
  • 那么描验,我們從哪兒加載這些類呢?
    答案是【class path】
    在IDEA中蔫慧,我們執(zhí)行了一段程序挠乳,在界面的下方权薯,我們沒有注意到的一段灰色的代碼姑躲,里面就藏著classpath


    idea界面

    在這段命令中,-classpath 或者 -cp后面接的就是這段程序找包的地方盟蚣。

  • 類的全限定類名(目錄層級)唯一確定了一個類

  • 包黍析,就是把許多類放在一起打的壓縮包

包的傳遞性依賴

  • 何為傳遞性依賴,即:你依賴的類還依賴了別的類
  • 于是屎开,恐怖的事情發(fā)生了:classpath hell(依賴地獄)
    • 全限定類名是類的唯一標識
    • 如果阐枣,我引用了A包和B包,B包中又引用了A包奄抽,就會出現(xiàn)多個同名類(A包)出現(xiàn)在classpath中蔼两,這就是下文即將說到的【包沖突
    • 如果出現(xiàn)了包沖突,默認的解法就是:優(yōu)先使用classpath排在前面的包逞度。
  • pom.xml (pom额划,就是Project Object Model)就是一份項目的說明書,看了pom.xml就知道這個項目是如何工作的档泽。

什么是包管理

簡單來說包管理的本質就是下面三點:

  • 你要使用一些第三方類俊戳,總要告訴JVM從哪里找吧?
  • 包管理的本質就是告訴JVM如何找到所需的第三方類庫
  • 以及成功的解決其中的沖突問題

Maven的包管理

Apache Maven馆匿,是一個軟件(特別是Java軟件)項目管理自動構建工具抑胎,由Apache軟件基金會所提供〗ケ保基于項目對象模型(縮寫:POM)概念阿逃,Maven利用一個中央信息片斷能管理一個項目的構建、報告和文檔等步驟。

Maven是一個劃時代的成就恃锉,必須強調羽历,Maven遠遠不止是包管理工具,還是一個自動化構建工具淡喜。Java在經歷了很多年的發(fā)展后秕磷,Maven的應運而生,是我們在龐大的Java項目中管理包不再是一件令人頭疼的事情炼团。

Maven —— 劃時代的包管理

  • Maven的中央倉庫(即遠程倉庫)澎嚣,按照一定的約定存儲包,我們可以在中央倉庫中瘟芝,找到所有的已經發(fā)布了的包易桃,用于我們查找及下載。
  • Maven的本地倉庫锌俱,默認位于~/.m2晤郑,下載的第三方包放在這里緩存
  • 而Maven最優(yōu)秀的地方就是,它規(guī)定了每一個包的命名規(guī)范贸宏,按照這種約定造寝,我們就能方便的在中央倉庫找到不同團隊、不同版本的包吭练,在項目中诫龙,也可以確定的引入我們想要引入的包。而Maven的命名規(guī)范主要是按照以下三個維度:
    • groupId / artifactId / version

groupidartifactId被統(tǒng)稱為“坐標”是為了保證項目唯一性而提出的鲫咽,如果你要把你項目弄到maven本地倉庫去签赃,你想要找到你的項目就必須根據(jù)這兩個id去查找。

groupId一般分為多個段分尸,這里我只說兩段锦聊,第一段為域,第二段為公司名稱箩绍。域又分為org孔庭、com、cn等等許多伶选,其中org為非營利組織史飞,com為商業(yè)組織。舉個apache公司的tomcat項目例子:這個項目的groupId是org.apache仰税,它的域是org(因為tomcat是非營利項目)构资,公司名稱是apache,artifactId是tomcat陨簇。

比如我創(chuàng)建一個項目吐绵,我一般會將groupId設置為cn.enoch迹淌,cn表示域為中國,enoch是我的名字己单,artifactId設置為testProj唉窃,表示你這個項目的名稱是testProj,依照這個設置纹笼,你的包結構最好是cn.enoch.testPro打頭的纹份,如果有個StudentDao,它的全路徑就是cn.enoch.testProj.dao.StudentDao

拓展:語義化版本

5.0.0-M1 【milestone 里程碑】
5.0.0-RC1 【Release candiate廷痘,正式版本的候選版本】
alpha:內部版本
beta:公測版本
SNAPSHOT:快照版本蔓涧,用于開發(fā)聯(lián)調的包

Maven 包沖突及解決

什么是包沖突

簡單的來說就是因為傳遞性依賴導致某一個包被引入了兩次,在classpath中出現(xiàn)了兩次笋额,從而導致我們在運行Java程序時元暴,classpath中后出現(xiàn)的那次引入的包不會被引入到項目中來。

包沖突可能會出現(xiàn)的異常

  • AbstractMethodError
  • NoClassDefFoundError
  • ClassNotFoundException
  • LinkageError

Maven傳遞性依賴的自動管理:

  • 原則:絕不允許最終的classpath出現(xiàn)同名不同版本的jar包
  • 依賴沖突的解決原則:最近的勝出
    遠兄猩,還是近茉盏?

    上圖中,最終形成的classpath枢冤,【C0.2】會被舍棄鸠姨,即,包沖突導致我們被迫使用了低版本的jar包

怎么解決呢掏导?

  • 首先:需要理清項目中的依賴關系享怀,找到哪一個依賴因為maven自動給舍棄導致的問題
  • 然后可能需要去看一下這個包的不同版本的源碼羽峰,找到為什么maven自動舍棄一些包依賴后會報異常(比如上面的例子:高版本被舍棄趟咆,但是我們用到了高版本才有的方法)
  • 解決它(兩種解法)
    1. 在我的項目中,直接依賴【C0.2】版本梅屉,這樣maven就會選擇最近的【C0.21】值纱,即在項目pom中直接引入該版本包的dependency。
    2. 排除掉【D包】的傳遞性依賴坯汤,這樣我們的依賴樹就只有一個【C0.2】包了 虐唠。使用exclusions,排除掉D包依賴的C包惰聂。


      exclusions的用法

如果兩個發(fā)生沖突的包”距離“一樣呢疆偿?

距離一樣,怎么辦

這張圖搓幌,【C0.1】和【C0.2】具體相同杆故,那么maven為了保證classpath同名包只有一個,就會選擇最先聲明的包溉愁,舍棄后者(比如先依賴的A处铛,就會選擇C0.1)

Maven的其他知識

scope

  • 依賴的scope(指定依賴只在scope中有效),實現(xiàn)依賴的隔離
    • compile/test/provided等等
    • main 生產代碼 / test 測試代碼
  • 最重要的有三個:(test / compile / provided)
    • <scope>test</scope>
      只有在測試代碼中(@TEST)才看得到這個包,在main里面無法使用這個包
    • <scope>compile</scope>
      在main和test都可見撤蟆,即編譯時候可見奕塑,運行時候可見,測試代碼可見家肯,生產代碼可見
    • <scope>provided</scope>
      只在編譯的時候有效龄砰,運行的時候就無效了,即只把這個包用于編譯讨衣。
      • 編譯:把源代碼變成字節(jié)碼的過程
      • 運行:jvm加載字節(jié)碼并開始運行的過程
      • NoClassDefFoundError
      • tomcat
        比如你的代碼經過編譯以后要部署到tomcat容器中寝贡,tomcat容器會幫你添加一些第三方依賴包,為了防止包沖突值依,我們就需要把這些包設置成provided

Maven查看依賴樹

  • mvn dependency:tree
    展示的是解決沖突后的依賴樹
  • 在idea中看
  • 安裝maven helper插件
    pom文件中圃泡,選擇dependency analyzer --》all dependencies as tree

(完)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市愿险,隨后出現(xiàn)的幾起案子颇蜡,更是在濱河造成了極大的恐慌,老刑警劉巖辆亏,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件风秤,死亡現(xiàn)場離奇詭異,居然都是意外死亡扮叨,警方通過查閱死者的電腦和手機缤弦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彻磁,“玉大人碍沐,你說我怎么就攤上這事≈则眩” “怎么了累提?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長磁浇。 經常有香客問我斋陪,道長,這世上最難降的妖魔是什么置吓? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任无虚,我火速辦了婚禮,結果婚禮上衍锚,老公的妹妹穿的比我還像新娘友题。我一直安慰自己,他們只是感情好构拳,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布咆爽。 她就那樣靜靜地躺著梁棠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪斗埂。 梳的紋絲不亂的頭發(fā)上符糊,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機與錄音呛凶,去河邊找鬼男娄。 笑死,一個胖子當著我的面吹牛漾稀,可吹牛的內容都是我干的模闲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼崭捍,長吁一口氣:“原來是場噩夢啊……” “哼尸折!你這毒婦竟也來了?” 一聲冷哼從身側響起殷蛇,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤实夹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粒梦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亮航,經...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年匀们,在試婚紗的時候發(fā)現(xiàn)自己被綠了缴淋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡泄朴,死狀恐怖重抖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情叼旋,我是刑警寧澤仇哆,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站夫植,受9級特大地震影響,放射性物質發(fā)生泄漏油讯。R本人自食惡果不足惜详民,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陌兑。 院中可真熱鬧沈跨,春花似錦、人聲如沸兔综。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涧窒,卻和暖如春心肪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纠吴。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工硬鞍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戴已。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓固该,卻偏偏與公主長得像,于是被迫代替她去往敵國和親糖儡。 傳聞我的和親對象是個殘疾皇子伐坏,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內容

  • 1. 包和類路徑 這里說的包是一個更寬的概念, 可以理解為把許多 Java 的 package 和其中的類放在一起...
    曉風殘月1994閱讀 256評論 0 0
  • 什么是包 JVM的工作 執(zhí)行一個類的字節(jié)碼 假如這個過程中碰到了新的類,則加載新類的字節(jié)碼 包就是把許多類放在一起...
    MoonRise__閱讀 198評論 0 0
  • 眾所周知握联,Java包管理是學習Java過程中一個很重要的內容著淆。本篇文章將著重介紹Java包管理以及Maven包管理...
    宣澤彬閱讀 5,135評論 0 1
  • 什么是包 JVM的工作相當簡單:執(zhí)行一個類的字節(jié)碼如果在該過程中碰到了新的類,再去加載該類 類路徑 Classpa...
    DeeJay_Y閱讀 1,031評論 0 1
  • JVM的工作原理 JVM的設計理念極其簡單拴疤,JVM只會做兩件事情: 執(zhí)行一個類的字節(jié)碼 執(zhí)行這個類的時候永部,若遇到了...
    憨憨二師兄閱讀 514評論 0 4