Maven是一個異常強大的構建工具,可以幫咱們自動化構建過程,從清理、編譯、測試到生成報告,再到打包和部署。經過Maven,咱們只須要輸入簡單的命令(如mvn clean install),就會幫咱們處理繁瑣的任務。Maven最大化的消除了構建的重複,抽象了構建生命週期,而且爲絕大部分的構建任務提供了已實現的插件。好比說測試,咱們只須要遵循Maven的約定編寫好測試用例,當咱們運行構建的時候,這些測試便會自動運行。除此以外,Maven能幫助咱們標準化構建過程。在Maven以前,十個項目可能有十種構建方式,但經過Maven,全部項目的構建命令都是簡單一致的。有利於促進項目團隊的標準化。java
Maven是筆者接觸的第一個脫離於IDE的命令行構建工具,筆者以前一直是基於Visual Studio下進行Windows驅動開發,並非很能明白Builder與IDE之間的區別。依賴大量的手工操做。編譯、測試、代碼生成等工做都是相互獨立的,很難一鍵完成全部工做。手工勞動每每意味着低效,意味着容易出錯。很難在項目中統一全部的IDE配置,每一個人都有本身的喜愛。也正是因爲這個緣由,一個在機器A上能夠成功運行的任務,到了機器B的IDE中可能就會失敗。linux
Make將本身和操做系統綁定在一塊兒了。也就是說,使用Make,就不能實現(至少很難)跨平臺的構建,這對於Java來講是很是不友好的。此外,Makefile的語法也成問題,不少人抱怨Make構建失敗的緣由每每是一個難以發現的空格或Tab使用錯誤。git
和Make同樣,Ant也都是過程式的,開發者顯式地指定每個目標,以及完成該目標所須要執行的任務。針對每個項目,開發者都須要從新編寫這一過程,這裏其實隱含着很大的重複。Maven是聲明式的,項目構建過程和過程各個階段所需的工做都由插件實現,而且大部分插件都是現成的,開發者只須要聲明項目的基本元素,Maven就執行內置的、完整的構建過程。這在很大程度上消除了重複。github
Ant是沒有依賴管理的,因此很長一段時間Ant用戶都不得不手工管理依賴,這是一個使人頭疼的問題。幸運的是,Ant用戶如今能夠藉助Ivy管理依賴。而對於Maven用戶來講,依賴管理是理所固然的,Maven不只內置了依賴管理,更有一個可能擁有全世界最多Java開源軟件包的中央倉庫,Maven用戶無須進行任何配置就能夠直接享用。web
可從apache官方下載最新的Maven 壓縮包,解壓便可。而後設置下系統的環境變量。以下所示:apache
M2HOME:maven安裝目錄服務器
Path:追加maven安裝目錄下的bin目錄網絡
在用戶目錄下,咱們能夠發現.m2文件夾。默認狀況下,該文件夾下放置了Maven本地倉庫.m2/repository。全部的Maven構件(artifact)都被存儲到該倉庫中,以方便重用。默認狀況下,~/.m2目錄下除了repository倉庫以外就沒有其餘目錄和文件了,不過大多數Maven用戶須要複製M2HOME/conf/settings.xml文件到~/.m2/settings.xmlapp
本節列舉出部分經常使用的Maven命令:dom
mvn -v 查看maven版本
mvn compile 編譯
mvn test 測試
mvn package 打包
mvn clean 刪除target
mvn install 安裝jar包到本地倉庫中
建立一個新工程
mvn archetype:generate -DgroupId=co.hoteam -DartifactId=Zigbee -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
就像Make的Makefile,Ant的build.xml同樣,Maven項目的核心是pom.xml。
首先建立一個名爲hello-world的文件夾,打開該文件夾,新建一個名爲pom.xml的文件,輸入其內容以下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.juvenxu.mvnbook</groupId> <artifactId>hello-world</artifactId> <version>1.0-SNAPSHOT</version> <name>Maven Hello World Project</name> </project>
代碼的第一行是XML頭,指定了該xml文檔的版本和編碼方式。緊接着是project元素,project是全部pom.xml的根元素,它還聲明瞭一些POM相關的命名空間及xsd元素,雖然這些屬性不是必須的,但使用這些屬性可以讓第三方工具(如IDE中的XML編輯器)幫助咱們快速編輯POM。
根元素下的第一個子元素modelVersion指定了當前POM模型的版本,對於Maven2及Maven 3來講,它只能是4.0.0。這段代碼中最重要的是groupId,artifactId和version三行。這三個元素定義了一個項目基本的座標,在Maven的世界,任何的jar、pom或者war都是以基於這些基本的座標進行區分的。
groupId定義了項目屬於哪一個組,這個組每每和項目所在的組織或公司存在關聯,譬如你在googlecode上創建了一個名爲myapp的項目,那麼groupId就應該是com.googlecode.myapp,若是你的公司是mycom,有一個項目爲myapp,那麼groupId就應該是com.mycom.myapp。本書中全部的代碼都基於groupId com.juvenxu.mvnbook。
artifactId定義了當前Maven項目在組中惟一的ID,咱們爲這個Hello World項目定義artifactId爲hello-world,本書其餘章節代碼會被分配其餘的artifactId。而在前面的groupId爲com.googlecode.myapp的例子中,你可能會爲不一樣的子項目(模塊)分配artifactId,如:myapp-util、myapp-domain、myapp-web等等。
version指定了Hello World項目當前的版本——1.0-SNAPSHOT。SNAPSHOT意爲快照,說明該項目還處於開發中,是不穩定的版本。隨着項目的發展,version會不斷更新,如升級爲1.0、1.1-SNAPSHOT、1.一、2.0等等。
最後一個name元素聲明瞭一個對於用戶更爲友好的項目名稱,雖然這不是必須的,但我仍是推薦爲每一個POM聲明name,以方便信息交流。 沒有任何實際的Java代碼,咱們就可以定義一個Maven項目的POM,這體現了Maven的一大優勢,它能讓項目對象模型最大程度地與實際代碼相獨立,咱們能夠稱之爲解耦,或者正交性,這在很大程度上避免了Java代碼和POM代碼的相互影響。好比當項目須要升級版本時,只須要修改POM,而不須要更改Java代碼;而在POM穩定以後,平常的Java代碼開發工做基本不涉及POM的修改。
項目主代碼和測試代碼不一樣,項目的主代碼會被打包到最終的構件中(好比jar),而測試代碼只在運行測試時用到,不會被打包。默認狀況下,Maven假設項目主代碼位於src/main/java目錄,咱們遵循Maven的約定,建立該目錄,而後在該目錄下建立文件com/juvenxu/mvnbook/helloworld/HelloWorld.java,其內容以下:
package com.juvenxu.mvnbook.helloworld; public class HelloWorld { public String sayHello() { return "Hello Maven"; } public static void main(String[] args) { System.out.print( new HelloWorld().sayHello() ); } }
關於該Java代碼有兩點須要注意。首先,在95%以上的狀況下,咱們應該把項目主代碼放到src/main/java/目錄下(遵循Maven的約定),而無須額外的配置,Maven會自動搜尋該目錄找到項目主代碼。其次,該Java類的包名是com.juvenxu.mvnbook.helloworld,這與咱們以前在POM中定義的groupId和artifactId相吻合。通常來講,項目中Java類的包都應該基於項目的groupId和artifactId,這樣更加清晰,更加符合邏輯,也方便搜索構件或者Java類。 代碼編寫完畢後,咱們使用Maven進行編譯,在項目根目錄下運行命令 mvn clean compile 便可。
clean告訴Maven清理輸出目錄target/,compile告訴Maven編譯項目主代碼,從輸出中咱們看到Maven首先執行了clean:clean任務,刪除target/目錄,默認狀況下Maven構建的全部輸出都在target/目錄中;接着執行resources:resources任務(未定義項目資源,暫且略過);最後執行compiler:compile任務,將項目主代碼編譯至target/classes目錄(編譯好的類爲com/juvenxu/mvnbook/helloworld/HelloWorld.Class)。
編輯~/.m2/settings.xml文件(若是沒有該文件,則複製$M2HOME/conf/settings.xml)。添加代理配置以下:
<settings> ... <pqroxies> <proxy> <id>my-proxy</id> <active>true</active> <protocol>http</protocol> <host>代理服務器主機名</host> <port>端口號</port> <!-- <username>***</username> <password>***</password> <nonProxyHosts>repository.mycom.com|*.google.com</nonProxyHosts> --> </proxy> </proxies> ... </settings>
衆所周知的緣由,國內有時候並不可以很順暢的訪問Maven的中央倉庫,每每咱們須要訪問國內的鏡像地址:
OSChina Maven教程
<mirror> <id>CN</id> <name>OSChina Central</name> <url>http://maven.oschina.net/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
(1)有時候由於衆所周知的網絡問題,致使Maven沒法訪問中央倉庫而後扔出一大堆錯誤,這個時候能夠嘗試參考上文中的設置代理。可是也要注意,是否是有一些私庫中的Repository。
(1)有時候執行mvn compile
時候會爆出沒法找到junit的錯誤,可能的解決方法有:
在Eclipse的Projects選項中使用Projects Clean
在pom.xml中引入junit依賴項,而且保證其scope爲compile:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
(2)有時候在Eclipse下執行mvn compile
或者相關命令時,會報某某文件出現不識別字符或者非UTF-8編碼,此時能夠作幾步檢查:
檢查對應的Java文件是否有Bom頭
檢查對應的Java文件的編碼
若是都沒有問題,在Eclipse中先將文件編碼設置爲GBK,再改回UTF-8試試。