在進行Java開發的過程當中,我接觸到了Maven這套構建工具。因此,花費了點時間學習了一下這套構建工具,在學習過程當中學習到的有關Maven的知識,在這裏分享給你們。html
首先,在介紹Maven這套工具以前,咱們得了解Maven是什麼。
Maven,在依地語中的意思是知識的積累,Maven在最初的時候,是做爲Jakarta的Turbine項目的構建工具。在Maven出現以前,不一樣的Java項目使用不一樣的Ant配置進行構建,而且將jar包包含在版本控制系統(CVS)中,沒有一套統一的構建工具。若是有一套工具,能夠擁有一套標準的方法來構建一個項目,而且能夠清楚的定義一個項目是由哪些部分組成的,擁有一種簡單的方法發佈項目的信息,在不一樣的項目之間能夠分享jar包。出於這個目的,Maven被創造了出來。java
Maven最初始的目標是讓開發者能夠在最短的週期內能夠快速的理解一個項目。爲了達到這個目的,Maven解決了一下幾個問題:apache
在使用Maven以前,咱們須要確保咱們已經安裝了Maven構建工具。沒有安裝Maven構建工具的,能夠參考官方提供的手冊參考如何安裝Mavenbash
在安裝了Maven之後,能夠經過命令 mvn -version
查看Maven的版本信息:app
$ mvn -version Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T19:57:37+08:00) Maven home: /usr/local/opt/maven Java version: 1.7.0_79, vendor: Oracle Corporation Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre Default locale: zh_CN, platform encoding: UTF-8 OS name: "mac os x", version: "10.10.2", arch: "x86_64", family: "mac"
接下來,咱們經過Maven建立一個新的項目開始。eclipse
$ mvn -B archetype:generate \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DgroupId=com.myapp \ -DartifactId=myapp
在上面的Maven命令中,咱們建立了一個名爲myapp
的普通Java項目。一旦咱們執行了上面的命令,就會在當前目錄下建立一個目錄爲myapp
的工程。在這個工程目錄下,包含了一個名爲pom.xml
的文件,這個新建立的pom文件內容大體以下:maven
<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.myapp</groupId> <artifactId>myapp</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>myapp</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>
這個pom文件表示了當前這個項目的項目對象模型(Project Object Model(POM)
。在Maven中,POM是它進行操做的基本單位。Maven的本質是以圍繞POM這個概念爲中心來管理整個項目的。POM中包含了項目中全部和項目相關的重要的信息,而且提供了相似一站式購物那樣的依賴管理方式,能夠很方便的找到當前項目關聯的全部依賴來項目。ide
上面的pom.xml文件中的內容,包含了當前這個項目的相關信息。咱們首先就上面這個POM文件中的一些元素,解釋下具體的含義:工具
project
這個元素是Maven的pom.xml文件的頂層元素。每一個POM文件都是以一個project
元素包裹的。modelVersion
這個元素指定了當前這個pom.xml文件使用的項目對象模型(POM)的版本。groupId
這個元素表示建立這個項目的組織的惟一標識。這個元素的值是區分一個項目的關鍵信息之一,它的值一般是由該項目的組織的域名的反寫產生的(和Java的包名的機制同樣)。artifactId
這個元素是惟一標識了該項目最終生成的artifact(能夠理解爲是咱們編寫代碼產生的一個程序,因此能夠理解爲是手工做品)。一個項目的artifact通常是一個jar
文件。一個項目最終生成的artifact的名字的格式是<artifactId>-<version>.<extension>
,好比上面的項目生成的artifact爲myapp-1.0.jar
。packaging
這個元素指定了該artifact打包的類型(好比:jar、war、ear等)。這不僅是意味着該artifact是以什麼方式打包,也指定了在構建過程當中會用到的特定的生命週期(所謂的生命週期,簡單的說就是構建的過程)。packaging
元素的默認值是JAR
。version
這個元素指定了項目生成的artifact的版本號。在版本號中會包含當前項目的進度,好比這裏的SNAPSHOT
。name
這個元素表示項目的名字,經常使用於生成的文檔中。url
這個元素表示該項目所在的站點,經常使用於生成的文檔中。description
這個元素提供了對項目的描述,一般用於生成的文檔中。在項目被建立之後,除了會生成上面的pom.xml文件,還會產生一個標準的目錄結構:佈局
myapp |-- pom.xml `-- src |-- main | `-- java | `-- com | `-- myapp | `-- App.java `-- test `-- java `-- com `-- myapp `-- AppTest.java
上面的目錄結構是Maven項目的標準佈局,項目的源代碼在目錄${basedir}/src/main/java
目錄下,而項目的測試代碼存放在目錄${basedir}/src/test/java
目錄下。對於${basedir},這裏表示的是包含了pom.xml文件的目錄,也就是項目的根目錄。
如今,咱們已經簡單介紹了maven相關的概念和maven標準的目錄結構。可是,在咱們使用Maven構建項目以前,咱們先簡單瞭解下Maven的生命週期。
Maven的構建機制,是圍繞生命週期(lifecycle)這個概念進行構建的。這意味着構建和發佈一個項目的整個過程是預先被定義了的。採用這種方式進行項目構建,可讓用戶能夠在學習不多的一部分命令的狀況下經過POM對項目進行構建。
在Maven中,內建了三種構建生命週期:default
、clean
、site
。default
生命週期處理項目的部署,clean
生命週期處理項目構建後的清理工做,site
生命週期對項目的站點文檔進行生成。
Maven的生命週期,又是由不一樣的階段(phase)構成的。每個生命週期,都包含了一系列的階段,每個階段都表示了生命週期中的一個狀態。好比,對於default
生命週期來講,包含了以下的這些階段:
Maven在執行default
生命週期的時候,會順序執行這些階段來完成不一樣的工做。
如今咱們已經安裝好Maven,而且對Maven的相關概念有了一些認識。下面,咱們能夠開始使用Maven對咱們的項目進行構建了。
在前面,咱們已經建立了一個名爲myapp
的項目。如今,咱們能夠經過下面的命令對這個項目進行編譯。
$ mvn compile
這個命令執行之後,會有相似下方的輸出:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ myapp --- ... [INFO] skip non existing resourceDirectory /Users/duke/practise/myapp/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ myapp --- [INFO] Changes detected - recompiling the module! ... [INFO] Compiling 1 source file to /Users/duke/practise/myapp/target/classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.159 s [INFO] Finished at: 2015-10-06T18:57:37+08:00 [INFO] Final Memory: 11M/156M [INFO] ------------------------------------------------------------------------
在執行這個命令之後,Maven會首先去下載全部構建當前項目所須要的插件,以及全部被當前項目所依賴全部依賴項目。從上面的輸出中能夠看出,咱們最終構建後的文件被輸出到目錄${basedir}/target/classes
中,這個目錄是Maven約定的一個標準目錄。使用Maven的好處之一,就是當咱們遵循Maven的約定之後,咱們可使用盡量少的配置就可讓Maven爲咱們構建項目。
如今,咱們已經成功地編譯了咱們的項目。接下來,咱們可讓Maven對單元測試進行編譯和執行,經過執行下面的命令,可讓Maven編譯和執行咱們寫的單元測試:
$ mvn test
上面的命令會有大體以下的輸出:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] ... [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ myapp --- [INFO] Nothing to compile - all classes are up to date ... [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ myapp --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Users/duke/practise/myapp/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ myapp --- [INFO] Surefire report directory: /Users/duke/practise/myapp/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.myapp.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.799 s [INFO] Finished at: 2015-10-06T19:08:08+08:00 [INFO] Final Memory: 13M/156M [INFO] ------------------------------------------------------------------------
從輸出中咱們能夠看到,Maven在編譯和執行單元測試以前,會首先編譯main
中的項目代碼,而後纔會對test
中的單元測試進行編譯和執行,並提供一個有關單元測試結果的簡單報告。
在這裏,咱們使用surefire
插件對單元測試進行執行。surefire
插件會對符合該插件約定的命名規則的單元測試文件進行搜索,而後進行執行。默認會執行如下命名規則的文件:
默認會排除如下命名規則的文件
固然,若是隻是須要對單元測試進行編譯而不須要執行,能夠運行命令mvn test-comiple
實現。
如今,咱們已經對項目進行編譯測試過了,咱們接下來須要對項目進行打包。當前項目,咱們在pom.xml中的packaging
元素中指定了打包的類型爲jar
。因此咱們能夠經過下面的命令來打jar包:
$ mvn package
執行這個命令的輸出大體以下:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myapp --- [INFO] Building jar: /Users/duke/practise/myapp/target/myapp-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.741 s [INFO] Finished at: 2015-10-06T19:41:05+08:00 [INFO] Final Memory: 10M/156M [INFO] ------------------------------------------------------------------------
Maven在執行這個命令的時候,會從pom.xml文件中得到打包的類型,在這個項目中爲jar包類型。而後將打出來的jar輸出到目錄${basedir}/target
下。
在打完包之後,咱們的jar包如今仍是留在咱們的項目的target目錄下,爲了將這個jar部署到咱們的本地倉庫(默認是~/.m2/repository
)中以供別的項目使用,咱們須要使用以下命令將當前項目的jar包部署到本地倉庫中:
$ mvn install
到目前爲止,咱們已經學習了怎麼對項目進行打包和部署到本地倉庫中了。
如今,咱們若是須要對構建除的文件進行清理,咱們須要使用以下的命令:
$ mvn clean [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ myapp --- [INFO] Deleting /Users/duke/practise/myapp/target [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.255 s [INFO] Finished at: 2015-10-06T19:47:25+08:00 [INFO] Final Memory: 6M/123M [INFO] ------------------------------------------------------------------------
這個命令會刪除target
目錄,由於在這個目錄下包含了咱們構建這個項目後輸出的全部文件。如今,咱們的項目就回到被構建以前了。
咱們若是使用IDE開發環境,咱們可使用Maven生成當前項目相關的IDE的描述文件。
對於IntelliJ IEDA環境,能夠用以下命令進行生成:
$ mvn idea:idea
對於eclipse環境,能夠用以下的命令生成:
$ mvn eclipse:eclipse