一、Maven是什麼?
Maven 是一個項目管理和構建自動化工具。Maven基於POM(Project object model),能夠管理項目的構建、報表、文檔等信息。
我們這裏主要講的Maven的項目構建功能。有了Maven,我們可以方便的管理Java項目的生命週期和依賴。通過定義一個POM文件,我們就可以自動的完成編譯、測試、打包甚至發佈等過程。
二、爲什麼要用Maven?
做過Java項目的童鞋都知道,一個項目中Java代碼經常會依賴其他的jar包中的class,或者依賴其它的項目,手動添加依賴是一個比較麻煩的事,尤其類似A依賴B,B又依賴C,C依賴D這種情況。
有了Maven,我們只需要在POM文件中定義依賴A,Maven就可以自動的添加其他所需的依賴了。
Maven還有很多有用的插件來幫助我們完成其他麻煩的事情,比如打包。Maven本身是Java開發,所以開發Maven的插件也比較簡單,但是我們這裏不深入研究。
另外,有人會問Maven和Ant的區別,我想說,你可以在《Maven權威指南》第一章的1.6節找到答案。
Maven還能降一個項目轉化爲Eclipse可以支持的項目,便於導入Eclipse。現在Eclipse也有插件支持Maven了,叫做 m2eclipse。
三、Maven有哪些常識?
Maven有個概念叫做“約定優於配置(Convention Over Configuration)”,意思就是很多東西都是預先約定好的,我們不需要進行修改,只需要按照這種方式來就好了。比如項目的目錄結構,Maven約定成如下:
目錄 | 目的 |
${basedir} | 存放 pom.xml和所有的子目錄 |
${basedir}/src/main/java | 項目的 java源代碼 |
${basedir}/src/main/resources | 項目的資源,比如說 property文件 |
${basedir}/src/test/java | 項目的測試類,比如說 JUnit代碼 |
${basedir}/src/test/resources | 測試使用的資源 |
${basedir}/target/classes | 編譯後的class文件 |
${basedir}/target | 打包的Jar文件 |
Maven有三套相互獨立的生命週期,Clean Lifecycle 在進行真正的構建之前進行一些清理工作。
- Clean Lifecycle 在進行真正的構建之前進行一些清理工作。
- Default Lifecycle 構建的核心部分,編譯,測試,打包,部署等等。
- Site Lifecycle 生成項目報告,站點,發佈站點。
核心部分的生命週期劃分爲以下幾個階段:
生命週期階段 | 描述 |
validate | 驗證項目是否正確,以及所有爲了完整構建必要的信息是否可用 |
generate-sources | 生成所有需要包含在編譯過程中的源代碼 |
process-sources | 處理源代碼,比如過濾一些值 |
generate-resources | 生成所有需要包含在打包過程中的資源文件 |
process-resources | 複製並處理資源文件至目標目錄,準備打包 |
compile | 編譯項目的源代碼 |
process-classes | 後處理編譯生成的文件,例如對Java類進行字節碼增強(bytecode enhancement) |
generate-test-sources | 生成所有包含在測試編譯過程中的測試源碼 |
process-test-sources | 處理測試源碼,比如過濾一些值 |
generate-test-resources | 生成測試需要的資源文件 |
process-test-resources | 複製並處理測試資源文件至測試目標目錄 |
test-compile | 編譯測試源碼至測試目標目錄 |
test | 使用合適的單元測試框架運行測試。這些測試應該不需要代碼被打包或發佈 |
prepare-package | 在真正的打包之前,執行一些準備打包必要的操作。這通常會產生一個包的展開的處理過的版本(將會在Maven 2.1+中實現) |
package | 將編譯好的代碼打包成可分發的格式,如JAR,WAR,或者EAR |
pre-integration-test | 執行一些在集成測試運行之前需要的動作。如建立集成測試需要的環境 |
integration-test | 如果有必要的話,處理包併發布至集成測試可以運行的環境 |
post-integration-test | 執行一些在集成測試運行之後需要的動作。如清理集成測試環境。 |
verify | 執行所有檢查,驗證包是有效的,符合質量規範 |
install | 安裝包至本地倉庫,以備本地的其它項目作爲依賴使用 |
deploy | 複製最終的包至遠程倉庫,共享給其它開發人員和項目(通常和一次正式的發佈相關) |
Maven插件和目標。使用Maven的過程,其實也是執行一個個Maven插件的過程。比如我們執行compile編譯的時候,其實是調用Maven的maven-compiler-plugin插件完成的。還有很多插件包括maven-clean-plugin,maven-dependency-plugin,maven-assembly-plugin等。每一個插件都有相應的目標,每一個目標都是一個可以單獨執行的任務。後面我們在命令行中使用
mvn archetype:create -DgroupId=com.dc.test -DartifactId=helloworld
快速創建一個Java項目的時候,我們其實也是執行了archetype插件的create目標,並給這個目標傳遞了groupId和artifactId的參數。
Maven倉庫。Maven運行的時候,需要的插件都是從中央倉庫(在配置文件中指定,有默認的,就像Linux的安裝源一樣)下載,下載之後,會存在本地的倉庫中,下次使用就不用再去下載了,Maven本身很小,但是本地倉庫在使用之後會越來越大(筆者用了幾次之後倉庫就用1G多了)。
Maven座標。Maven座標定義了一組標識,它們可以用來唯一標識一個項目,一個依賴,或者Maven POM裏的一個插件。一般座標使用groupId, artifactId, version和packaging來實現:
名稱 | 作用 |
groupId | 團體,公司,小組,組織,項目,或者其它團體。團體標識的約定是,它以創建這個項目的組織名稱的逆向域名(reverse domain name)開頭。來自Sonatype的項目有一個以com.sonatype開頭的groupId,而Apache Software的項目有以 org.apache開頭的groupId。
|
artifactId | 在groupId下的表示一個單獨項目的唯一標識符。 |
version | 一個項目的特定版本。發佈的項目有一個固定的版本標識來指向該項目的某一個 |
packaging | 項目的類型,默認是jar,描述了項目打包後的輸出。類型爲jar的項目產生一個 |
POM文件(pom.xml)。當Maven運行的時候它向項目對象模型(POM)查看關於這個項目的信息。POM回答類似這樣的問題:這個項目是什麼類型的?這個項目的名稱是什麼?這個項目的構建有自定義麼?詳細的POM語法查看Maven官網的POM Reference
下面是一個由Maven Archetype插件的create目標創建的默認的pom.xml文件:
<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>org.sonatype.mavenbook.ch03</groupId>
<artifactId>simple</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
四、怎麼快速用Maven構建一個Java項目?
1) 首先下載Maven,地址:http://maven.apache.org/
2) 修改 Maven 的本地倉庫地址,在Maven安裝目錄下的conf/settings.xml中修改localRepository節點
3) 如果要使用m2eclipse插件(這裏用的Eclipse是Luna版本),配置
修改插件的Maven配置文件路徑爲外部的Maven。
打開Eclipse菜單Window - Preference,修改如下
4) 快速創建一個HelloWorld項目。我們
其中-DinteractiveMode表示我們使用的是非交互模式,在創建過程中我們不需要選擇和輸入參數。
我們查看目錄,發現默認生成了如下的代碼
以及默認的POM文件
切換到pom.xml文件所在目錄,
使用mvn compile進行編譯(會默認執行compile前面所有生命週期階段)
使用mvn test進行測試(會默認執行test前面所有的生命週期階段)
需要用到其他依賴的時候,在如下地址進行搜索:
比如需要使用mahout
拷貝結果中的pom到本地項目中POM文件中對應的位置即可,就可以自動完成依賴的管理。
要直接支持某個含main函數的類時,可以使用exec-maven-plugin,詳細瞭解移步http://mojo.codehaus.org/exec-maven-plugin/
要打包jar文件時,可以使用shade插件,支持精簡jar包,去掉沒有用到的東西。另外也有一些其他打包的插件,可以自己查閱。shade插件深入瞭解移步http://maven.apache.org/plugins/maven-shade-plugin/
要將項目轉換爲Eclipse支持的項目,使用mvn eclipse:eclipse命令,我們就可以使用Eclipse導入了。
五、參考文獻:
《maven權威指南》
《maven實戰》
Maven官網:
Oracle 教程:
http://www.oracle.com/technetwork/cn/community/java/apache-maven-getting-started-1-406235-zhs.html
http://my.oschina.net/heguangdong/blog/50302