Windows7下Maven環境搭建及其使用

Windows7下Maven環境搭建及其使用

1.軟體下載

1.下載JDK

下載地址:

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

下載的安裝包為jdk-8u101-windows-x64.exe

2.下載Maven

下載地址:http://maven.apache.org/download.cgi

下載的是最新版本apache-maven-3.3.9-bin.zip

注:安裝Maven3.3需要提前安裝好JDK 1.7以上版本

2.JDK安裝配置

1.安裝JDK

雙擊安裝包,點選下一步,如圖:

點選更改選擇JDK安裝的目錄後(這個很重要,記住安裝路徑),點選下一 步,完成JDK的安裝。

這個時候,就在安裝JDK了。等出現下圖,表示JDK安裝成功:

2.配置JDK

右擊計算機,選擇屬性->高階系統設定->環境變數,點選系統變數的新建按鈕。變數名為JAVA_HOME,變數值為你安裝JDK時的路徑,我當時安裝在C盤下,所以變數值就為[C:\Program
Files\Java\jdk1.8.0_101],配置完成後點選確定。

在系統變數中找到Path後,在變數值最後加上:[%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;]   如圖:

完成後點選確定按鈕,點選系統變數的新建按鈕,變數名為CLASSPATH,變數值為[.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar]    如圖:

以上就完成了JDK的安裝與配置,下面來測試安裝是否成功,開始-執行-cmd進入命令框,在命令框中輸入Java -version,出現下圖表示安裝成功!

3.Maven安裝配置

【必須先下載並安裝JDK,配置JDK的環境變數JAVA_HOME,否則maven無法使用eclipse安裝maven外掛後必須重新定位maven到本地maven目錄】

1.安裝Maven 

將下載好的Maven安裝包解壓到磁碟中,我解壓的路徑為D:\apache-maven-3.3.9

配置環境變數 
   MAVEN_HOME : D:\apache-maven-3.3.9
   MAVEN : %MAVEN_HOME%\bin 
  (可選) MAVEN_OPTS : -Xms256m -Xmx512m 

右擊計算機,選擇屬性->高階系統設定->環境變數,點選系統變數的新建按鈕。新增新的系統環境變數MAVEN_HOME,設定其值為剛才解壓的maven路徑:[D:\apache-maven-3.3.9],如圖:

配置系統的path變數,在其尾部加新增[;%MAVEN_HOME%\bin;],如圖:

(還有一個可選的環境變數MAVEN_OPTS,該環境變數主要是配置Maven在使用jdk的時候指定JVM屬性的。如指定其值為“-Xms256m
-Xmx512m”)

接下來我們可以在命令視窗使用mvn -v來驗證一下Maven是否安裝成功。如能正確輸出Maven的安裝版本,則表示它安裝成功了,如圖:

2.理解“倉庫”概念

 
首次執行完mvn -version後,會在使用者目錄下建立一個.m2的目錄(比如:C:\Users\當前使用者名稱\.m2\),這個目錄是maven的“本地倉庫”,倉庫是maven中一個很重要的概念。

  試想一下,我們會在工作中同時建立很多專案,每個專案可能都會引用一些公用的jar包(.NET中是dll檔案),一種作法是每個專案裡,都複製一份這些依賴的jar包(或dll檔案),這樣顯然不好,相同的檔案在硬碟上儲存了多份,太佔用空間,而且這些依賴的jar包(或dll檔案)的版本也不太好管理(比如某個公用的jar包,從1.0升級到2.0,如果所有引用這個jar包的專案都需要更新,必須一個個專案的修改)。

  maven的倉庫則很好的解決了這些問題,它在每臺機器上建立一個本機倉庫,把本機上所有maven專案依賴的jar包統一管理起來,而且這些jar包用“座標”來唯一標識(注:座標是另一個重要的概念,後面還會講到,這裡只要簡單理解成“唯一識別某個jar包檔名、版本號”的標識即可),這樣所有maven專案就不需要再象以前那樣把jar包複製到lib目錄中,整個maven專案看起來十分清爽。

3.配置Maven環境

  在Maven中提供了一個settings.xml檔案來定義Maven的全域性環境資訊。這個檔案會存在於Maven的安裝目錄的conf子目錄下面,或者是使用者家目錄的.m2子目錄下面。我們可以通過這個檔案來定義本地倉庫、遠端倉庫和聯網使用的代理資訊等。

  其實相對於多使用者的PC機而言,在Maven安裝目錄的conf子目錄下面的settings.xml才是真正的全域性的配置。而使用者家目錄的.m2子目錄下面的settings.xml的配置只是針對當前使用者的。當這兩個檔案同時存在的時候,那麼對於相同的配置資訊使用者家目錄下面的settings.xml中定義的會覆蓋Maven安裝目錄下面的settings.xml中的定義。使用者家目錄下的settings.xml檔案一般是不存在的,但是Maven允許我們在這裡定義我們自己的settings.xml,如果需要在這裡定義我們自己的settings.xml的時候就可以把Maven安裝目錄下面的settings.xml檔案拷貝到使用者家目錄的.m2目錄下,然後改成自己想要的樣子。

  先來看一個基本的settings.xml的樣子:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/path/to/local/repo</localRepository>
<interactiveMode>true</interactiveMode>
<offline>false</offline>
<pluginGroups>
</pluginGroups>
<proxies>
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
</proxies>
<servers>
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
</server>
<mirrors>
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
</settings>

settings.xml中主要包括以下元素:

localRepository:表示Maven用來在本地儲存資訊的本地倉庫的目錄。預設是使用者家目錄下面的.m2/repository目錄。

<localRepository>/path/to/local/repo</localRepository>

interactiveMode:表示是否使用互動模式,預設是true;如果設為false,那麼當Maven需要使用者進行輸入的時候,它會使用一個預設值。

<interactiveMode>true</interactiveMode>

offline:表示是否離線,預設是false。這個屬性表示在Maven進行專案編譯和部署等操作時是否允許Maven進行聯網來下載所需要的資訊。

<offline>false</offline>

pluginGroups:在pluginGroups元素下面可以定義一系列的pluginGroup元素。表示當通過plugin的字首來解析plugin的時候到哪裡尋找。pluginGroup元素指定的是plugin的groupId。預設情況下,Maven會自動把org.apache.maven.plugins和org.codehaus.mojo新增到pluginGroups下。

 <pluginGroups> </pluginGroups>

proxies:其下面可以定義一系列的proxy子元素,表示Maven在進行聯網時需要使用到的代理。當設定了多個代理的時候第一個標記active為true的代理將會被使用。

<proxies>
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
</proxies>

servers:其下面可以定義一系列的server子元素,表示當需要連線到一個遠端伺服器的時候需要使用到的驗證方式。這主要有username/password和privateKey/passphrase這兩種方式。

   <servers>
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
</server>

mirrors:用於定義一系列的遠端倉庫的映象。我們可以在pom中定義一個下載工件的時候所使用的遠端倉庫。但是有時候這個遠端倉庫會比較忙,所以這個時候人們就想著給它建立映象以緩解遠端倉庫的壓力,也就是說會把對遠端倉庫的請求轉換到對其映象地址的請求。每個遠端倉庫都會有一個id,這樣我們就可以建立自己的mirror來關聯到該倉庫,那麼以後需要從遠端倉庫下載工件的時候Maven就可以從我們定義好的mirror站點來下載,這可以很好的緩解我們遠端倉庫的壓力。在我們定義的mirror中每個遠端倉庫都只能有一個mirror與它關聯,也就是說你不能同時配置多個mirror的mirrorOf指向同一個repositoryId。

  <mirrors>
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
</mirrors>

l  id:是用來區別mirror的,所有的mirror不能有相同的id

l  mirrorOf:用來表示該mirror是關聯的哪一個倉庫,其值為其關聯倉庫的id。當要同時關聯多個倉庫時,這多個倉庫之間可以用逗號隔開;當要關聯所有的倉庫時,可以使用“*”表示;當要關聯除某一個倉庫以外的其他所有倉庫時,可以表示為“*,!repositoryId”;當要關聯不是localhost或用file請求的倉庫時,可以表示為“external:*”。

l  url:表示該映象的url。當Maven在建立系統的時候就會使用這個url來連線到我們的遠端倉庫。

profiles:用於指定一系列的profile。profile元素由activation、repositories、pluginRepositories和properties四個元素組成。當一個profile在settings.xml中是處於活動狀態並且在pom.xml中定義了一個相同id的profile時,settings.xml中的profile會覆蓋pom.xml中的profile。

  <profiles>
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
</profiles>

activation:這是profile中最重要的元素。跟pom.xml中的profile一樣,settings.xml中的profile也可以在特定環境下改變一些值,而這些環境是通過activation元素來指定的。

在上面這段程式碼中,當所有的約束條件都滿足的時候就會啟用這個profile。

jdk:表示當jdk的版本滿足條件的時候啟用,在這裡是1.4。這裡的版本還可以用一個範圍來表示,如

<jdk>[1.4,1.7]</jdk>表示1.4、1.5、1.6和1.7滿足;

activeProfiles:底包含一系列的activeProfile元素,表示對於所有的pom都處於活躍狀態的profile。

  <activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>

4.Maven使用入門

到目前為止,已經大概安裝好了Maven,現在開始建立一個最簡單的Hello World專案。

1.建立專案

在命令列輸入:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -Dversion=1.0

回車,如圖:

執行Maven命令(goal)archetype:generate,並且設定了一些引數

( -DgroupId=com.mycompany.app -DartifactId=my-app -Dversion=1.0) 
【mvn archetype:generate
建立maven專案;

-DgroupId=com.mycompany.app組ID;

-DartifactId=my-app專案名稱

-Dversion=1.0版本】 

如果你是首次執行該命令(goal),maven將要花一些時間從maven庫去把最新的工具包(Maven把它叫作artifacts)下載到你的本地倉庫(local
repository)中,所以這個時候需要Internet連線。Maven預設的本地庫是%USER_HOME%\.m2\repository\,比如我的本地庫路徑為:C:\User\fulei\.m2\repository\。

命令執行完後你將看到maven生成了一個名為my-app的目錄,這個名字就是你在命令中指定的artifactId,進入該目錄,你將發現以下標準的專案結構:

其中:src/main/java
目錄包含了專案的原始碼,src/test/java 目錄包含了專案的測試程式碼,pom.xml是專案的專案物件模型(Project
Object Model or POM)。

2.POM程式碼介紹

就像Make的Makefile、Ant的build.xml一樣,Maven專案的核心是pom.xml。POM(Project
Object Model,專案物件模型)定義了專案的基本資訊,用於描述專案如何構建,宣告專案依賴等。下面列出這個POM的內容:

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>my-app</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

程式碼第一行是XML頭,指定了該xml文件的版本和編碼方式。緊接著是project元素,project是所有pom.xml的根元素,它還宣告瞭一些POM相關的名稱空間及xsd元素,雖然這些屬性不是必須的,但是用這些屬效能夠讓第三方工具能夠快速編輯POM。

根元素的第一個元素modelVersion指定了當前POM模型的版本,對於Maven2及Maven3來說,它只能是4.0.0。

這段程式碼中最重要的是groupID、artifactID和version的三行。這三個元素定義了一個專案基本的座標,在Maven專案中,任何的jar、pom或者version都是以基於這些基本的座標進行區分的。

groupID定義了專案屬於哪個組,這個組往往和專案所在的組織或公司存在關聯。比如在googlecode上建立了一個myapp的專案,那麼groupID就是com.googlecode.myapp。

· 簡而言之:

· modelVersion: 這個XML檔案所使用的POM格式的版本

· groupId: 相當於這個project的所有者或者機構的一個標識,一般是com.company.xxx這種格式

· artifactId: 這個project最後所生成的文件(jar、war)的名字,比如對於junit這個開源的project,它的artifactId就是junit

· packaging: 這個project的打包的型別,一般是war、jar等值

· version: project的版本

· name: project的名字,生成文件等內容的時候會用的這個名字

3.主程式碼

專案主程式碼和測試程式碼不同,專案的主程式碼會被打包到最終的構件中(如jar),而測試程式碼只在執行測試時用到,不會被打包。預設情況下,Maven專案主程式碼位於src/main/java目錄,所以在該目錄下建立檔案com/mycompany/app/App.java,其程式碼內容如下:

package com.mycompany.app;
/**
* Hello world!
*/
public class App 
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}

關於Java程式碼有兩點需要注意。首先,在絕大多數情況下,應該把專案主程式碼放到src/main/java目錄下(遵循Maven的約定),而無須額外的配置,Maven會自動搜尋該目錄找到專案主程式碼,其次,該Java類的包命是com.mycompany.app

這與POM中定義的groupID和artifactID相吻合,專案中Java類的包都應該基於專案的groupID和artifactID,這樣更加清晰,更加符合邏輯,也可以方便搜尋構件或Java類。

4.編譯 

使用Maven進行編譯,在專案根目錄下執行命令mvn clean compile,會得到如下輸出:

clean告訴Maven清理輸出目錄target/,compile告訴Maven編譯專案主程式碼,從輸出中看到Maven實現執行了clean:clean任務,刪除target/目錄。預設情況下,Maven構建的所有輸出都在target/目錄中;接著執行resources:resources任務(未定義專案資源,暫時略過);之後執行compile:compile任務,將專案主程式碼編譯至target/classes目錄(編譯好的類為com/mycompany/app/App.class)

5.測試 

主程式碼與測試程式碼分別位於獨立的目錄中,Maven專案中的預設的測試程式碼了目錄為src/test/java。

在Java世界中,JUnit是事實上的單元測試標準,要使用JUnit,要為專案新增JUnit依賴,專案POM程式碼中:

  <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

程式碼中有dependencies元素,該元素下可以包含多個dependency元素以宣告專案的依賴,這裡新增了一個依賴–groupID是junit,artifactID是junit,version是3.8.1,有了這段宣告,Maven就能夠自動下載junit-3.8.1.jar。有了Maven,它會自動訪問中央倉庫,下載需要的檔案。也可以自己訪問該倉庫,打卡路徑junit/junit/3.8.1/,就能看到junit-3.8.1pom和junit-3.8.1.jar。

上述POM程式碼中還有一個值為test的元素scope,scope為依賴範圍,若依賴範圍為test則表示該依賴只對測試有效。換句話說,測試程式碼中的import
JUnit程式碼是沒有問題的,但是如果在主程式碼中用import JUnit程式碼,就會對造成編譯錯誤。如果不宣告依賴範圍,那麼預設值就是compile,表示該依賴對主程式碼和測試程式碼都有效。

開啟測試用例程式碼,在src/test/java目錄下的AppTest.java,程式碼如下:

package com.mycompany.app;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest 
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

呼叫Maven執行測試,執行mvn clean test,如圖:

測試程式碼通過編譯後在target/test-classes下生成了二進位制檔案,緊接著surefire:test任務執行測試,surefire是Maven中負責執行測試的外掛,這裡它執行測試用例AppTest,並輸出測試報告,顯示一共執行了多少測試,失敗了多少,出錯了多少,跳過了多少。顯然,測試通過了。

6.打包

在命令列上輸入:cd my-app回車,進入到專案路徑下,再輸入mvn package回車這時命令列將會列印出各種動作,並且以下面一段資訊結束,如圖:

此時,maven在my-app下面建立了一個新的目錄target/,構建打包後的jar檔案my-app-1.0.jar就存放在這個目錄下。編譯後的class檔案放在target/classes/目錄下面,測試class檔案放在target/test-classes/目錄下面。

7.執行

執行下面的命令:

java -cp target/my-app-1.0.jar com.mycompany.app.App,結果如圖:

至此,我們得到了專案的輸出。

8.安裝JAR包

如果需要的話,可以複製這個jar檔案到其他專案的Classpath中從而使用my-app類。還需要一個安裝的步驟,執行mvn
clean install:

在打包之後,有執行了安裝任務install:install。從輸出可以看到該任務將專案輸出的jar安裝到了Maven本地倉庫中,可以開啟相應的資料夾看到my-app專案的pom和jar。我們說只有將構件下載到本地倉庫中,才能由所有Maven專案使用。

到這裡就說完了建立,編譯,測試,打包以及安裝,大部分的專案也就是做這些事情。

Maven最主要的命令:mvn clean compile、mvn clean test、mvn
clean package、mvn clean install。

Maven有一套build的生命週期,是按照一套順序走下來的,這一套順序就叫一個生命週期(lifecycle)。一個生命週期分為多個階段(build
phase),每一個build phase是由目標(goal)組成的,一個goal其實就是一個任務,目標可以繫結到生命週期階段上。一個生命週期階段可以繫結多個外掛目標。當maven在構建過程中逐步的通過每個階段時,會執行該階段所有的外掛目標。比如執行打包命令:

mvn package時,會先執行compile,再執行test,最後才是package打包。

好了,maven的核心概念就簡單的介紹到這裡。