安裝以後開始建立一個最簡單的Hello World項目。 ###3.1 編寫POM### 就像Make的Makefile,Ant的build.xml,Maven的核心是pom.xml。POM(Project Object Model,項目對象模型)定義了項目的對象信息,用於描述項目如何構建,聲明項目依賴等等。 先爲Hello World項目編寫一個最簡單的pom.xml。 首先建立一個名爲hello-world的文件夾,打開文件夾,新建一個pom.xml文件,輸入以下內容:java
<?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.learn.mvn</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元素,雖然這些屬性不是必須的,但使用這些屬性能讓第三方工具能提供該xml的隨筆功能。
modelVersion指定當前POM模型的版本,對於Maven2及Maven3來講,它只能是4.0.0。
groupId、artifactId、version這三個元素定義了一個項目基本的座標。groupId定義了項目屬於哪一個組,這個組每每和項目所在的組織或公司有關聯。譬如在googlecode上創建一個名爲myphone的組,那麼groupId就是com.googlecode.myphone。
artifactId定義了當前Maven項目在組中惟一的ID,一般狀況下是一個項目或者子項目的名字。例如myphone組下有一個項目爲google-phone,你可能會爲不一樣的子項目(模塊)分配artifactId,如google-phone-util、google-phone-domain、google-phone-web。
version指定了項目當前的版本 1.0-SNAPSHOT,SNAPSHOT意爲快照,說明還在開發中,是不穩定的版本。version會不斷升級,如1.0、1.1-SNAPSHOT。 ###3.2 編寫主代碼### 項目主代碼會被打包到最終的構件中(如jar),而測試代碼只會在運行測試時用到。默認狀況下,項目主代碼位於src/main/java目錄,建立在該目錄下的好處是無須額外的配置,在之後使用的過程當中,Maven會自動搜尋該目錄找到項目主代碼。
咱們編寫HelloWorld.java所在目錄是src/main/java/com/learn/mvn/helloworld/HelloWorld.java,則該java的文件包名爲:com.learn.mvn.helloworld,這與POM中定義的gruopId和artifactId相吻合,通常來講,項目中java類的包名都應該基於項目的groupId和artifactId,這樣更加清晰,也更符合邏輯,也方便搜索構件。web
package com.learn.mvn.helloworld; public class HelloWorld { public String sayHello() { return "Hello Maven!"; } public static void main(String[] args) { System.out.println(new HelloWorld().sayHello()); } }
代碼編寫完後,使用maven進行編譯,在項目根目錄下運行命令 mvn clean compile會獲得如下輸出:
clean告訴Maven清理出target/目錄,compile告訴Maven編譯項目主代碼。從輸出中能夠看到Maven首先執行了clean:clean任務,刪除target/目錄。默認狀況下,Maven的全部輸出都在target目錄中;接着執行resources:resources任務;最後執行compiler:compile任務,將項目主代碼編譯至target/classes目錄。
能夠看到其中執行了三個插件,maven-clean-plugin、maven-resources-plugin、maven-compile-plugin,clean會清理輸出目錄target/,resouce會處理資源文件,compile會編譯項目主代碼放在target/classes中(編譯好的類爲com/learn/mvn/helloworld/HelloWorld.Class)。 ###3.3 編寫測試代碼### 爲了保持項目結構清晰,主代碼與測試代碼應該分別位於獨立的目錄中。Maven項目中的默認的測試代碼目錄是src/test/java。
爲了使用JUnit進行單元測試咱們須要在pom.xml中添加對JUnit構件的依賴,修改後的pom.xml以下:apache
<?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.learn.mvn</groupId> <artifactId>hello-world</artifactId> <version>1.0-SNAPSHOT</version> <name>Maven Hello World Project</name> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> <scope>test</scope> </dependency> </dependencies> </project>
代碼中添加了dependencies元素,該元素下能夠包含多個dependency元素以聲明項目的依賴。這裏添加了Junit的一個座標。有了這段聲明,Maven會自動訪問中央倉庫 http://search.maven.org/#browse 下載所需的文件。上面pom.xml代碼中還有一個值爲test的元素scope,scope爲依賴範圍,若依賴範圍爲test,則表示該依賴只對測試有效,則在主代碼中使用該JUnit就會出錯,而在測試代碼中使用不會出錯。scope默認值爲compile,表示該依賴對主代碼和測試代碼都有效。
接下來編寫測試代碼:app
package com.learn.mvn.helloworld; import static org.junit.Assert.assertEquals; import org.junit.Test; public class HelloWorldTest { @Test public void testSayHello() { HelloWorld helloWorld = new HelloWorld(); String result = helloWorld.sayHello(); assertEquals("Hello Maven!", result); } }
一個典型的單元測試包含三個步驟:1.準備測試類和數據;2.執行要測試的行爲;3.驗證測試結果。
測試用例編寫完以後就能夠掉用Maven執行測試:mvn clean test:dom
E:\MavenProject\hello-world>mvn clean test [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Hello World Project 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world --- [INFO] Deleting E:\MavenProject\hello-world\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-worl d --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e . build is platform dependent! [INFO] skip non existing resourceDirectory E:\MavenProject\hello-world\src\main\ resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil d is platform dependent! [INFO] Compiling 1 source file to E:\MavenProject\hello-world\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ he llo-world --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e . build is platform dependent! [INFO] skip non existing resourceDirectory E:\MavenProject\hello-world\src\test\ resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-w orld --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil d is platform dependent! [INFO] Compiling 1 source file to E:\MavenProject\hello-world\target\test-classe s [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello-world --- [INFO] Surefire report directory: E:\MavenProject\hello-world\target\surefire-re ports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.learn.mvn.helloworld.HelloWorldTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.26 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.750 s [INFO] Finished at: 2015-09-13T23:59:21+08:00 [INFO] Final Memory: 11M/29M [INFO] ------------------------------------------------------------------------
命令行雖然只輸入了mvn clean test,而maven實際所作的處理有:clean:clean(執行maven-clean-plugin的clean目標,下面類同)、resources:resources、compile:compile、resources:testRescources、compile:testCompile、surefire:test。須要知道的是,在Maven執行測試(surefire:test)以前,會先執行項目主資源的處理、主代碼的編譯、測試資源的處理、測試代碼的編譯等工做,這是maven生命週期的一個特性。測試代碼經過編譯以後在target/test-classes下生成了測試文件。
maven在執行上訴處理以前,會讀取pom.xml,執行一些操做,如查看相關依賴是否在本地倉庫中存在,若是不存在則前往中央倉庫下載。在上面的例子中,maven會去下載junit-4.9.pom和junit-4.9.jar文件。
###3.4 打包和運行### hello-world的POM中沒有指定打包類型,使用默認的打包類型jar。執行命令 mvn clean package進行打包。maven會在打包以前執行編譯、測試等操做,打包後的文件位於target/中,它時根據artifact-version.jar規則來進行命名的。
爲了讓其餘的maven項目直接能夠該jar包,還須要執行一個安裝的命令, mvn clean install ,將其安裝在本地倉庫中。maven
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hello-world --- [INFO] Installing E:\MavenProject\hello-world\target\hello-world-1.0-SNAPSHOT.ja r to C:\Users\Administrator\.m2\repository\com\learn\mvn\hello-world\1.0-SNAPSHO T\hello-world-1.0-SNAPSHOT.jar [INFO] Installing E:\MavenProject\hello-world\pom.xml to C:\Users\Administrator\ .m2\repository\com\learn\mvn\hello-world\1.0-SNAPSHOT\hello-world-1.0-SNAPSHOT.p om [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
打開本地倉庫的相應目錄能夠看到hello-world項目的pom和jar。
已經學習了Maven的最主要命令:mvn clean compile、mvn clean test、mvn clean package、mvn clean install。執行compile以前會先執行clean,執行test以前會先執行compile,執行package以前會先執行test、執行install以前會先執行package。
在HelloWorld類中存在一個main方法,可是默認打包生成的jar是不能直接運行的,咱們須要額外在pom.xml中配置maven-shade-plugin插件來實現這個功能。函數
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.learn.mvn.helloworld.HelloWorld</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
plugin元素在POM中的相對位置應該在<project><build><plugins>下面。而後從新執行mvn clean package進行打包。看jar包的MANIFEST.MF文件能夠看到有一行Main-Class: com.learn.mvn.helloworld.HelloWorld 在項目根目錄中執行該jar文件,能夠看到咱們的main函數執行成功了。
###3.5 使用Archetype生成項目骨架### Maven中有一些約定:在項目的根目錄中放置pom.xml,在src/main/java目錄中放置項目的主代碼,在src/test/java中放置項目的測試代碼.... 若是咱們每次都手動創建這些文件夾,那就太費勁了。爲此,maven提供了Archetype以幫助咱們快速勾勒出項目骨架。
在workspace目錄下輸入:mvn archetype:generate命令。以下圖:工具
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 1: 1.0-alpha-1 2: 1.0-alpha-2 3: 1.0-alpha-3 4: 1.0-alpha-4 5: 1.0 6: 1.1 Choose a number: 6: Define value for property 'groupId': : com.learn.mvn Define value for property 'artifactId': : my-app Define value for property 'version': 1.0-SNAPSHOT: : 1.0-SNAPSHOT Define value for property 'package': com.learn.mvn: : com.learn.mvn.myapp Confirm properties configuration: groupId: com.learn.mvn artifactId: my-app version: 1.0-SNAPSHOT package: com.learn.mvn.myapp Y: : Y [INFO] ------------------------------------------------------------------------- --- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.1
maven會要求你選擇archetype的類型,通常狀況下使用默認的maven-archetype-quickstart,無需輸入直接回車便可,而後會要求選擇這類型的版本,推薦maven-archetype-quickstart使用1.1。而後會要求輸入該項目的一些配置信息,如groupId、artifactId、version、package。
這裏使用的是一個基本的archetype,若是有不少項目擁有相似的自定義項目結構以及配置文件,則能夠定義本身的Archetype,在之後的項目中用本身的Archetype生成骨架。 ###3.6 Maven在Eclipse中配置###性能