Maven技術解析

Maven簡單介紹

Maven是一個項目管理工具。強大,但是很容易使用。

它包含了:

  • 一個項目對象模型 (Project Object Model);
  • 一組標準集合;
  • 一個項目生命周期(Project Lifecycle);
  • 一個依賴管理系統(Dependency Management System);
  • 用來運行定義在生命周期階段(phase)中插件(plugin)目標(goal)的邏輯。

當你使用Maven的時候,你用一個明確定義的項目對象模型來描述你的項目,然后 Maven 可以應用橫切的邏輯, 這些邏輯來自一組共享的(或者自定義的)插件。

如果看完簡介,你還迷糊的,那么我想說:這很正常!請心無旁騖地往下看,學習完這個入門教程,該懂的你就都懂了。


溫馨提示:本文的最后一個主題是個動手示例,如果大段的文字定義讓你非常沒有效率,那么,你可以在任何時候先來動手完成這個示例。找找感覺,然后再來看這些枯燥的定義。

安裝Maven

在Mac OSX上安裝Maven

你可以從http://maven.apache.org/download.html下載Maven的二進制版本。下載最新 的,下載格式最方便你使用的版本。找個地方存放它,并把存檔文件解開。如果你把存 檔文件解壓到 /usr/local/maven-2.0.9 ;你可能會需要創建一個符號鏈接,那樣就能更容易使用,當你升級Maven的時候也不再需要改變環境變量。
/usr/local % ln -s maven-2.0.9 maven /usr/local % export M2_HOME=/usr/local/maven /usr/local % export PATH=/usr/local/maven/bin:/usr/local/bin:/usr/local/maven/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/java/latest/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/usr/local/bin
將Maven安裝好后,你還需要做一些事情以確保它正確工作。你需要將它的 bin 目錄 (該例中為 /usr/local/maven/bin)添加到你的命令行路徑下。你還需要設置 M2_HOME 環境變量,其對應值為Maven的根目錄(該例中為 /usr/local/maven)。
注意
在OSX Tiger和OSX Leopard上安裝指令是相同的。有報告稱Maven 2.0.6正 和XCode的預覽版本一起發布。如果你安裝了XCode,從命令行運行 mvn 檢 查一下它是否可用。 XCode把Maven安裝在了/usr/share/maven。我們強烈建 議安裝最新版本的Maven 2.0.9,因為隨著Maven 2.0.9的發布很多bug被修 正了,還有很多改進。
你還需要把 M2_HOME 和 PATH 寫到一個腳本里,每次登陸的時候運行這個腳本。把下 面的幾行加入到 .bash_login。
export M2_HOME=/usr/local/maven export PATH=/usr/local/maven/bin:/usr/local/bin:/usr/local/maven/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/java/latest/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/usr/local/bin
一旦你把這幾行加入到你的環境中,你就可以在命令行運行Maven了。
注意
這些安裝指令假設你正運行bash。

在Microsoft Windows上安裝Maven

在Windows上安裝Maven和在Mac OSX上安裝Maven十分類似,最主要的區別在于安裝位置和設置環境變量。在這里假設Maven安裝目錄是 c:\Program Files\maven-2.0.9 ,但 是,只要你設置的正確的環境變量,把Maven安裝到其它目錄也一樣。當你把Maven解 壓到安裝目錄后,你需要設置兩個環境變量——PATH和M2_M2_HOME。設置這兩個環境變量,鍵入下面的命令:
C:\Users\tobrien > set M2_HOME=c:\Program Files\maven-2.0.9
C:\Users\tobrien > set PATH=%PATH%;%M2_HOME%\bin

在命令行設置環境變量后,你可以在當前會話使用Maven,但是,除非你通過控制面 板把它們加入系統變量,你將需要每次登陸系統的時候運行這兩行命令。你應該在 Microsoft Windows中通過控制面板修改這兩個變量。

在Linux上安裝Maven

遵循第 2.3.1 節 “在Mac OSX上安裝Maven”的步驟,在Linux機器上安裝Maven。

掃清障礙

學習新技能的時候,有太多的內容需要去探索,快速有效的獲取信息非常重要。掌握下邊兩個方法,可以助你快速掌握maven。

help 插件的使用方法

tags:maven help

目的:使用help插件,配合不同的參數,查看maven插件的相關信息。

  • 命令:mvn help:describe -Dplugin=插件名稱mvn 插件名稱:help
    作用:查看插件的描述信息。

  • 命令:mvn help:describe -Dplugin=插件名稱 -Dmojo=目標名稱
    作用:查看插件的某個【目標】的簡介信息。

  • 命令:mvn help:describe -Dplugin=插件名稱 -Dmojo=目標名稱 -Ddetail
    或者這么寫 mvn 插件名稱:help -Ddetail=true -Dgoal=目標名稱
    作用:查看help插件的某個【目標】的詳細信息。

maven自有參數

使用 mvn --help 命令查看maven自有參數信息,比如-D、-X、-e


Maven核心概念

約定大于配置

在必要的情況下才進行自定義,否則使用maven默認設置。


插件(plugin), 目標(goal)參數生命周期,生命周期階段

插件

是一組【目標】的集合。maven使用插件來完成特定的任務。

比如:創建項目使用archetype插件,編譯項目使用compiler插件,使用install插件編譯、測試、打包項目并安裝到本地庫中等。
注意install插件,他同時也是一個maven生命周期階段,因為在執行install時,它使用了多個插件,完成了多個目標。

先記下,后邊再說。


目標(goal)

  • 被用來完成明確的任務。
  • 它可以作為單獨的目標運行,也可以作為一個大的構建的一部分和其它目標一起運行。
  • 一個目標是Maven中的一個“工作單元(unit of work)“。

你會在maven的輸出中經常看到一個詞:Mojo。mojo就是goal。A Maven plain Old Java Object.

示例:

help是一個maven插件。它包括9個目標。

help:active-profiles
help:all-profiles
help:describe
help:effective-pom
help:effective-settings
help:evaluate
help:expressions
help:help
help:system
  • 使用命令 mvn 插件名稱:help 查看插件的目標。

參數

目標定義了一些參數,可以在執行目標時,向目標傳遞參數值來達成個性化的結果。

  • 使用命令 mvn help:describe -Dplugin=插件名稱 -Dmojo=目標名稱 -Ddetail 查看目標的參數。

生命周期

生命周期就是一個項目從無到有的整個過程,這個過程里包含了多個階段(比如創建、編譯、測試、打包/構建、部署),每個階段就叫做生命周期階段。Maven的生命周期是抽象的。
這意味著生命周期本身不做任何實際的工作。在Maven的設計中,實際的任務(如編譯源代碼)都交由插件來完成。maven命令行的輸入往往就對應了生命周期階段,如mvn package就表示執行默認生命周期階段package(構建)。

  • 生命周期和插件兩者協同工作,密不可分。
  • 生命周期是一系列有序的生命周期階段的集合,對所有的構建過程進行了抽象和統一。
  • Maven可以支持許多不同的生命周期,最常用的是Maven生命周期。

包括:

清理
初始化
編譯
測試
打包(package)
集成測試
驗證
部署
站點生成

以上的每個生命周期階段都可以綁定一個或者多個插件行為,而且Maven為大多數構建步驟編寫并綁定了默認插件。
比如package這個生命周期階段的編譯任務可能就會調用maven-jar-plugin來完成,測試任務就會調用maven-surefire-plugin來完成。

坐標

Maven坐標定義了一組標識,它們可以用來唯一標識一個項目,一個依賴,或者Maven POM里的一個插件。

Maven項目坐標的構成元素:groupId, artifactId, version和packaging。這些組合的標識符拼成了一個項目的坐標。

但是packaging不是一個項目唯一標識符的必須部分。

Maven坐標通常用冒號來作為分隔符來書寫,格式:groupId:artifactId:packaging:version。
比如:mavenbook:my-app:jar:1.0-SNAPSHOT.
這也適用于項目依賴,比如項目包含了一個對junit:junit:jar:3.8.1的依賴。

標識解釋

1 groupId:

團體,公司,小組,組織,項目,或者其它團體的逆向域名。比如Apache Software的項目經常以org.apache作為groupId。

2 artifactId

在groupId下表示一個單獨項目的唯一標識符。

3 version:

一個項目的特定版本。發布的項目有一個固定的版本標識來指向該項目的某一個特定的版本。正在開發中的項目用一個特殊的標識“SNAPSHOT”標記。正式發布版是“release”或“stable”標記。

4 packaging:

項目的類型,默認是jar,描述了項目打包后的輸出。類型為jar的項目產生一個JAR文件,類型為war的項目產生一個web應用。

倉庫(Repositories)

當你第一次運行Maven的時候,你會注意到Maven從一個遠程的Maven倉庫下載了許多文件。如果這個簡單的項目是你第一次運行Maven,那么當觸發resources:resource目標的時候,它首先會做的事情是去下載最新版本的Resources插件。在Maven中,構件和插件是在它們被需要的時候從遠程的倉庫取來的。初始的Maven下載包的大小相當的?。?.8兆),其中一個原因是這個初始Maven不包括多余的插件。它只包含了幾近赤裸的最少值,而在需要的時候再從遠程倉庫去取。Maven自帶了一個用來下載Maven核心插件和依賴的遠程倉庫地址/ http://repo1.maven.org/maven2 。你常常會寫這樣一個項目,這個項目依賴于一些既不免費也不公開的包。在這種情況下,你需要要么在你組織的網絡里安裝一個定制的倉庫,要么手動的安裝這些依賴。默認的遠程倉庫可以被替換,或者增加一個你組織維護的自定義Maven倉庫的引用。有許多現成的項目允許組織管理和維護公共Maven倉庫的鏡像。

是什么讓Maven倉庫成為一個Maven倉庫的呢?

Maven倉庫是通過結構來定義的,一個Maven倉庫是項目構件的一個集合,這些構件存儲在一個目錄結構下面,它們的格式能很容易的被Maven所理解。在一個Maven倉庫中,所有的東西存儲在一個與Maven項目坐標十分匹配的目錄結構中。你可以打開瀏覽器,然后瀏覽中央Maven倉庫http://repo1.maven.org/maven2/ 來看這樣的結構。你會看到坐標為org.apache.commons:commons-email:1.1的構件能在目錄/org/apache/commons/commons-email/1.1/下找到,文件名為commons-email-1.1.jar。Maven倉庫使用約定的標準目錄格式來存儲構件。

Maven從遠程倉庫下載構件和插件到你本機上,存儲在你的本地Maven倉庫里。一旦Maven已經從遠程倉庫下載了一個構件,它將永遠不需要再下載一次,因為maven會首先在本地倉庫查找插件,然后才是其它地方。在Windows XP上,你的本地倉庫很可能在C:\Documents and Settings\USERNAME.m2\repository,在Windows Vista上,會是C:
\Users\USERNAME.m2\repository。在Unix系統上,你的本地倉庫在~/.m2/repository。

如果你運行 mvn install 命令,Maven會把本地項目的構件安裝到本地倉庫。你能從這個命令的輸出看到,Maven把本地項目的JAR文件安裝到了本地Maven倉庫。Maven在本地項目中通過本地倉庫來共享依賴。如果你開發了兩個項目—— 項目A和項目B——項目B依賴于項目A產生的構件。當構建項目B的時候,Maven會從本地倉庫取得項目A的構件。

Maven倉庫既是一個從遠程倉庫下載的構件的緩存,也允許你的項目相互依賴。

依賴管理 (Dependency Management)

創建一個項目所需要的資源引用稱為依賴。

一個復雜的項目將會包含很多依賴,也有可能包含依賴于其它構件的依賴。這是Maven最強大的特征之一,它支持了傳遞性依賴(transitive dependencies)。假如你的項目依賴于一個庫,而這個庫又依賴于五個或者十個其它的庫(就像Spring或者Hibernate那樣)。你不必找出所有這些依賴然后把它們寫在你的pom.xml里,你只需要加上你直接依賴的那些庫,Maven會隱式的把這些庫間接依賴的庫也加入到你的項目中。Maven也會處理這些依賴中的沖突,同時能讓你自定義默認行為,或者排除一些特定的傳遞性依賴。

在Maven中的一個依賴不僅僅是一個JAR。它還包括了一個POM文件,這個POM可能也聲明了對其它構件的依賴。這些依賴的依賴叫做傳遞性依賴,Maven倉庫不僅僅存貯二進制文件,也存儲了這些構建的元數據(metadata),才使傳遞性依賴成為可能。

讓我們看一下這個目錄:~/.m2/repository/junit/junit/3.8.1/。這里會有文件junit-3.8.1.jar 和junit-3.8.1.pom,還有Maven用來驗證已下載構件準確性的校驗和文件。需要注意的是Maven不只是下載JUnit的JAR文件,它同時為這個JUnit依賴下載了一個POM文件。Maven同時下載構件和POM文件的這種行為,對Maven支持傳遞性依賴來說非常重要。
當Maven通過一組Maven坐標來處理依賴構件的時候,它也會獲取依賴構建的POM,通過依賴的POM來尋找傳遞性依賴。那些傳遞性依賴就會被添加到當前項目的依賴列表中。

Maven同時也提供了一種機制,能讓你排除一些你不想要的傳遞性依賴。

Maven也提供了不同的依賴范圍(dependency scope)。當一個依賴的范圍是test的時候,說明它在Compiler插件運行compile 目標的時候是不可用的。它只有在運行compiler:testCompile和surefire:test目標的時候才會被加入到classpath中。當用Maven來創建WAR或者EAR,你可以配置Maven讓它在生成的構件中捆綁依賴,你也可以配置Maven,使用provided范圍,讓它排除WAR文件中特定的依賴。provided范圍告訴Maven一個依賴在編譯的時候需要,但是它不應該被捆綁在構建的輸出中。當你開發web應用的時候provided范圍變得十分有用,你需要通過Servlet API來編譯你的代碼,但是你不希望Servlet API的JAR文件包含在你web應用的WEB-INF/lib 目錄中。

站點生成和報告 (Site Generation and Reporting)

另外一個Maven的重要特征是,它能生成文檔和報告。在項目的目錄下,運行以下命令:

mvn site

這將會運行site生命周期階段。它不像默認生命周期那樣,管理代碼生成,操作資源,編譯,打包等等。Site生命周期只關心處理在src/site目錄下的site內容,還有生成報告。在這個命令運行過之后,你將會在target/site 目錄下看到一個項目web站點。載入target/site/index.html你會看到項目站點的基本外貌。它包含了一些報告,它們在左手邊的導航目錄的“項目報告”下面。它也包含了項目相關的信息,依賴和相關開發人員信息。

在這個站點上,你會注意到一些默認的報告已經可以訪問了,有一個報告詳細描述了測試的結果。這個單元測試報告描述了項目中所有單元測試的成功和失敗信息。另外一個報告生成了項目API的JavaDoc。Maven提供了很完整的可配置的報告,像Clover報告檢查單元測試覆蓋率,JXR報告生成HTML源代碼相互間引用,這在代碼審查的時候非常有用,PMD報告針對各種編碼問題來分析源代碼,JDepend報告分析源代碼中各個包之間的依賴。通過在pom.xml中配置那些報告被包含在構建中,站點報告就可以被定制了。

自己動手體會一下

通過一個經典的控制臺 Hello world! 程序來體會maven的使用過程,包括創建、編譯、測試、打包 ,并運行程序。

第一步:定位目錄

在命令窗口中定位到將要創建項目的目錄下。比如我的是:D:\Project\mavenTest\quickstart>

第二步:創建項目

使用archetype插件創建項目,輸入以下命令:mvn archetype:generate ,回車,等。。。 然后,不出意外的話,你會看到屏幕輸出了上千種archetype支持的項目類型。在末尾你會看到要求你輸入的地方,就是這個:Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 756: 不翻譯了,你一定要能看懂。

因為我們要創建的是一個簡單的示例程序,所以什么都不輸入,直接回車。
屏幕輸出maven-archetype-quickstart項目類型的幾個不同版本.
輸入對應的序號(我輸入的是6),然后回車。

按照屏幕輸出,依次輸入:groupId,artifactId,version,package. 

屏幕會輸出你填寫的項目信息,要求你確認,輸入 Y ,回車,確認。

maven會根據你的設置開始下載依賴文件并創建項目。 當你看到Build Success時,項目就被創建好了,打開你的項目位置查看你的項目。maven在項目根目錄下生成了一個POM.xml文件,這個是項目對象模型描述文件,maven就是根據這個文件的描述來構建你的項目的,打開看一下。

第三步:編譯項目

使用compiler插件創建項目,輸入以下命令:mvn compiler:compile ,回車,等。。。
maven開始下載依賴文件并編譯項目。 當你看到Build Success時,項目就被編譯好了,你還可以看到詳細的編譯結果信息。

第四步:打包項目 / 構建項目

使用maven默認的生命周期階段命令package來打包項目,輸入以下命令:mvn package ,回車,等。。。
maven開始下載依賴文件并編譯項目。 當你看到Build Success時,項目就被打包好了,你還可以看到詳細的編譯結果信息。項目的根目錄會出現一個target目錄,存放了項目打包后的文件。

當然,你也可以不使用maven生命周期的默認package命令,而是自己動手使用多個插件來完成這個任務。

第五步:運行項目

如果前邊的都成功完成的話,現在就可以運行一下項目看看結果了。

命令行輸入:java -cp target/quickstart-1.1.jar maven.archetype.quickstart.App 回車。
應該輸出了Hello world!。


到這里為止,你已經了解了maven最核心的概念,明白了maven的結構,而且親自使用maven成功構建了一個項目。

所以,本文到此就結束了。

接下來,到實際的工作中去使用maven,不斷磨練自己的技藝吧!

附錄

apache maven 官網

基于 Jenkins 快速搭建持續集成環境

maven的快速設置

maven核心插件列表

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容

  • |-1-更新內容[6.從倉庫解析依賴的機制(重要)] 1Maven倉庫作用 倉庫用來存儲所有項目使用到構件,在ma...
    zlcook閱讀 6,094評論 0 25
  • Maven的基本了解 什么是Maven? Maven就是Apache下的一個開源項目。它是用純java開發的。是一...
    Bcome閱讀 2,847評論 0 7
  • 我jdk版本是1.7.0_95,在網上查了一下1.7屬于java7maven3.3+版本都支持java7,所以我使...
    liangxifeng833閱讀 1,278評論 0 2
  • 首先私服是一種衍生出來的特殊的Maven遠程倉庫,構建私服的好處請看3.5私服 可以幫助大家建立私服的倉庫管理軟件...
    zlcook閱讀 10,580評論 0 32
  • 一直以來,便很喜歡三毛的這句話:如果有來生,我愿做一棵樹。站成永恒,沒有悲歡的姿勢。一半在塵土里安詳,一半...
    2401期待閱讀 322評論 0 1