maven clean/install/build/package命令行詳解
1 是什么

Apache的優秀開源項目,是Java項目的構建和管理工具。
Maven 是 Apache 組織下的一個跨平臺的項目管理工具,它主要用來幫助實現項目的構建、測試、打包和部署。Maven 提供了標準的軟件生命周期模型和構建模型,通過配置就能對項目進行全面的管理。它的跨平臺性保證了在不同的操作系統上可以使用相同的命令來完成相應的任務。Maven 將構建的過程抽象成一個個的生命周期過程,在不同的階段使用不同的已實現插件來完成相應的實際工作,這種設計方法極大的避免了設計和腳本編碼的重復,極大的實現了復用。
2 能干什么
用maven方便的創建項目,基于archetype可以創建多種類型的java項目
Maven倉庫對jar包(artifact)進行統一管理,避免jar文件的重復拷貝和版本沖突
團隊開發,管理項目的RELEASE和SNAPSHOT版本,方便多模塊(Module)項目的各模塊之間的快速集成
簡介
本文將介紹基于 Apache Maven 3 的項目構建的基本概念和方法。Maven 是一套標準的項目構建和管理工具,使用統一規范的腳本進行項目構建,簡單易用,摒棄了 Ant 中繁瑣的構建元素,并具有較高的可重用性。讀完本文,你將了解 Maven 的基本概念和使用它進行項目構建的基本方法。
Maven vs Ant
Ant 也是 Apache 組織下的一個跨平臺的項目構建工具,它是一個基于任務和依賴的構建系統,是過程式的。開發者需要顯示的指定每一個任務,每個任務包含一組由 XML 編碼的指令,必須在指令中明確告訴 Ant 源碼在哪里,結果字節碼存儲在哪里,如何將這些字節碼打包成 JAR 文件。Ant 沒有生命周期,你必須定義任務和任務之間的依賴,還需要手工定義任務的執行序列和邏輯關系。這就無形中造成了大量的代碼重復。
Maven 不僅是一個項目構建工具還是一個項目管理工具。它有約定的目錄結構(表 1)和生命周期,項目構建的各階段各任務都由插件實現,開發者只需遵照約定的目錄結構創建項目,再配置文件中生命項目的基本元素,Maven 就會按照順序完成整個構建過程。Maven 的這些特性在一定程度上大大減少了代碼的重復。
3 常用命令
maven install
maven的install可以將項目本身編譯并打包到本地倉庫,這樣其他項目引用本項目的jar包時不用去私服上下載jar包,直接從本地就可以拿到剛剛編譯打包好的項目的jar包,很靈活,避免每次都需要重新往私服發布jar包的痛苦。
修改服務端比如manage層和dao層的項目的時候如果eclipse沒有自動編譯,則在調試的時候容易出很奇怪的錯誤,就是明明代碼已經改好了,但是debug的時候還是在報錯,這就是沒有項目沒有編譯完成造成的,看到的改好的代碼沒有變成class,因此,服務端的文件改動之后如果發現沒有效果的時候要記得問題可能是沒有編譯,這時候可以使用maven的install命令編譯
IDEA可以很方便創建project和module,但是修改各個module的版本的時候,會遇到import報錯的情況,這就是maven倉庫中沒有對應的包,仍然需要使用到install,注意要使用lifecycle里面的install
這樣就可以將已有的module打包到maven倉庫,再進行修改版本號,不會影響項目里的其他module
mvn clean
清理環境,清除target文件夾。
mvn compile
編譯,將Java源文件編譯成class文件。
mvn test
執行test目錄下的測試用例。
mvn package
打包,將Java工程打成jar包。
跳過單元測試:mvn clean package -Dmaven.test.skip=true
4 避坑指南
對于多模塊的項目,注意父 pom 會設置 JDK 版本,注意對齊版本號!
項目對象模型 POM
它是使用Maven工作時的基本組件,是一個xml文件。它被放在工程根目錄下,文件命名為pom.xml。
POM包含了關于工程和各種配置細節的信息,Maven使用這些信息構建工程。
POM 即 Project Object Module,項目對象模型,在 pom.xml 文件中定義了項目的基本信息、源代碼、配置文件、開發者的信息和角色、問題追蹤系統、組織信息、項目授權、項目的 url、以及構建項目所用的插件,依賴繼承關系。開發人員需按照 maven 定義的規則進行 POM 文件的編寫
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
在每個 POM 文件中都含有的元素是該 project 的坐標,包含三個基本元素:
groupId 定義了項目屬于哪個組,這有助于在大的范圍上區別項目
artifactId 定義了這個項目在組中唯一的 ID,通常是工程的名稱
groupId 和 artifactId 一起定義了artifact 在倉庫中的位置。
name 是一個用戶友好的項目名稱
除了項目坐標外,modelVersion 指定 POM 模型的版本,version 指明當前項目的版本,packaging 指定了項目發布時的打包類型。
Maven 插件和倉庫
Maven 本質上是一個插件框架,它的核心并不執行任何具體的構建任務,僅僅定義了抽象的生命周期,所有這些任務都交給插件來完成的。每個插件都能完成至少一個任務,每個任務即是一個功能,將這些功能應用在構建過程的不同生命周期中。這樣既能保證拿來即用,又能保證 maven 本身的繁雜和冗余。
將生命周期的階段與插件目標相互綁定,就可以在特定的階段完成具體的構建任務。例如下面的代碼就是要在 validate 這個階段執行 maven-antrun-plugin 的 run 目標,具體的任務在 元素中定義。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Maven 項目中的插件,依賴和項目構建的輸出都可以由 Maven 的坐標進行唯一的區分,基于這種機制,Maven 將所有項目的構件文件放置在一個統一的位置,也就是 Maven 倉庫。所有 Maven 項目可以從同一個 Maven 倉庫中獲取自己所需要的依賴 JAR,這節省了磁盤資源。實際的 Maven 項目中不需要存儲依賴的文件,只需要在 POM 文件中生成依賴關系,在構建的時候 Maven 就會自動去倉庫中下載。
在安裝了 Maven 的機器上,會生成一個 ~.m2\repository 目錄,這個目錄被稱為本地倉庫,當 Maven 查找需要的依賴時,首先會在本地查找,如果本地倉庫中存在,則直接使用,否則 Maven 回去遠程倉庫查找,查找到后下載到本地進行使用。遠程中央倉庫的地址為 http://repo1.maven.org/。當然還有一些鏡像倉庫可供使用,有興趣的讀者可以參考 Maven 官方網站的相關介紹。
當個人所在的網絡無法訪問公共的 Maven 倉庫時,可以在 settings.xml 中設置代理服務器。打開 ~.m2\settings.xml,如果沒有則復制 $Maven_HOME/conf/settings.xml 到此路徑下,加入
1
2
3
4
5
6
7
8
9
10
依賴、聚合和繼承
依賴
我們項目中依賴的 Jar 包可以通過依賴的方式引入,通過在 dependencies 元素下添加 dependency 子元素,可以聲明一個或多個依賴。通過控制依賴的范圍,可以指定該依賴在什么階段有效。Maven 的幾種依賴范圍:
傳遞依賴
依賴具有傳遞性,例如 Project A 依賴于 Project B,B 依賴于 C,則 B 對 C 的依賴關系也會傳遞給 A。
如果我們的項目引用了一個jar包,而該jar包又引用了其他jar包。那么,
在默認情況下,項目編譯時, Maven會把直接引用和間接引用的jar包都
下載到本地( ~/.m2/repository )。
如果我們不需要這種傳遞性依賴,可用
1
2
3
4
5
6
假設第三方的 jar 包中沒有使用
1
2
3
4
5
6
7
8
9
10
依賴沖突
若項目中多個jar同時引用了相同的jar時,會產生依賴沖突,但Maven采用了兩種
避免沖突的策略,因此在Maven中是不存在依賴沖突:
短路優先
本項目 =》 A.jar =》B.jar =》 X.jar
本項目=》 C.jar =》 Xjar
聲明優先
若引用路徑長度相同時,在pom.xmI中誰先被聲明,就使用誰
多模塊項目 / 聚合
現實中一個項目往往是由多個 project 構成的,在進行構建時,我們當然不想針對多個 project 分別執行多次構建命令,這樣極容易產生遺漏也會大大降低效率。Maven 的聚合功能可以通過一個父模塊將所有的要構建模塊整合起來。
? 父模塊pom文件的配置: packaging 類型必須是pom
1
2
3
4
?聚合子模塊:使用modules標簽
1
2
3
4
5
將父模塊的打包類型聲明為 POM,通過
聚合
1
2
3
4
父類型的模塊,不需要有源代碼和資源文件,也就是說,沒有 src/main/java 和 src/test/java 目錄。Maven 會首先解析聚合模塊的 POM 文件,分析要構建的模塊,并通過各模塊的依賴關系計算出模塊的執行順序,根據這個潛在的關系依次構建模塊。將各子模塊聚合到父模塊中后,我們就可以對父模塊進行一次構建命令來完成全部模塊的構建。
繼承
在面向對象的編程中我們學會了繼承的概念,繼承是可重用行即消除重復編碼的行為。Maven 中繼承的用意和面向對象編程中是一致的。與聚合的實現類似,我們通過構建父模塊將子模塊共用的依賴,插件等進行統一聲明,在聚合和繼承同時使用時,我們可以用同一個父模塊來完成這兩個功能。
例如將 com.dugeng.parent 這個模塊聲明為 project1 和 project2 的父模塊,那么我們在 project1 和 2 中用如下代碼聲明父子關系,如
1
2
3
4
5
6
由于父模塊只是用來聲明一些可共用的配置和插件信息,所以它也像聚合模塊一樣只需要包括一個 POM 文件,其它的項目文件如 src/main/java 是不需要的。
聚合和繼承存在一些共性和潛在的聯系,在實際的應用中,經常將聚合模塊的父模塊和繼承的父模塊定義為同一個。
并不是所有的 POM 元素都可以被繼承,如下是可繼承的元素列表。
可繼承元素列表
名稱 描述
groupId 項目組 ID
version 項目版本
description 描述信息
organization 組織信息
inceptionYear 創始年份
url 項目的 url 地址
developers 開發者
contributors 貢獻者信息
distributionManagerment 部署信息
issueManagement 缺陷跟蹤系統
ciManagement 持續繼承信息
scm 版本控制信息
mailingList 郵件列表信息
properties 自定義的屬性
dependencies 依賴配置
dependencyManagement 依賴管理配置
repositories 倉庫配置
build 源碼目錄,插件管理等配置
reporting 報告配置
排除依賴
如果我們只想下載直接引用的jar包,那么需要在pom.xml 中做如下配置(給出需要排除的坐標)
Maven 屬性
在 POM 文件中常常需要引用已定義的屬性以降低代碼的冗余,提高代碼的可重用性,這樣不僅能降低代碼升級的工作量也能提高代碼的正確率。有些屬性是用戶自定義的,有些屬性是可以直接引用的已定義變量。
Maven 的可用屬性類型可分為 5 種,它們分別是:
內置屬性。這種屬性跟 Maven Project 自身有關,比如要引入當前 Project 的版本信 息,那么只需要在使用的位置引用 ${version} 就行了。
Setting 屬性。上文中已經提到 Maven 自身有一個 settings.xml 配置文件,它里面含有包括倉庫,代理服務器等一些配置信息,利用 ${settings.somename} 就可以得到文件里相應元素的值。
POM 屬性。這種屬性對應 POM 文件中對應元素的值,例如 p r o j e c t . g r o u p I d 對 應 了 < g r o u p I d > < / g r o u p I d > 中 的 值 , {project.groupId} 對應了
系統環境變量。可以使用 env.${name} 來獲得相應 name 對應的環境變量的值,例如 ${env.JAVA_HOME} 得到的就是 JAVA_HOME 的環境變量值。
用戶自定義變量。這種類型的變量是使用最頻繁和廣泛的變量,完全由用戶自己定義。在 POM 文件中加入 元素并將自定義屬性作為其子元素。格式如
1
2
3
Maven 3 特性
Maven 3 在性能和靈活性方面都比 Maven2 有了很大提升,它的新特性總結起來有以下幾點:
兼容低版本 Maven,也就是向后兼容,因此用戶可以將 Maven2 的項目移植到 Maven3 上來。
性能優化。CPU 利用率更高,內存消耗更小,經過優化的 Maven3 比 Maven2 構建速度快出 50% 以上,這對于構建大型項目的開發者來說無疑會節省大量的時間。
在早先的版本中,開發者必須在子模塊中指定父版本,當進行代碼的遷移或升級時,這會帶來額外的維護工作,Maven3.1 將會消除在子模塊上指定父版本的需要。
4.Maven3 改善了錯誤報告,它會在錯誤報告中提供指向 Maven Wiki 頁面的鏈接,這樣開發者可以方便的查看更全面的錯誤描述和可能的原因。
增加了 Maven Shell,通常我們可以在系統自帶的 console 里執行 Maven 命令,但是通過自安裝的 Maven Shell 可以提高生成速度,它是一個是 Maven 的命令行接口工具,可以緩存解析過的 POM,避免了重復調用 Maven 的啟動成本。Maven Shell 不屬于 Maven 發行包的一部分,需要單獨下載。
M2Eclipse 實現了 Maven 和 Eclipse 的集成,與一個使用更廣泛的 IDE 進行集成從而為開發者帶來的便利是不言而喻的。
總結
Maven 有著許多實用的特點,它使用了標準的目錄結構和部署。這就使得開發人員能夠適應不同的項目,并且不用學習任何結構方面新的東西,也不用掌握特殊的指令來構建結構。當然,Maven 的使用還不夠普及,相信隨著時間的推移,它的功能會更完善,使用的人群也會越來越廣泛。
JAR Maven XML
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。