Maven學習筆記

引用一個正式的 Apache Maven的定義: Maven是一個項目管理工具,它包含了一個項目對象模型 (Project Object Model),一組標準集合,一個項目生命週期(Project
Lifecycle),一個依賴管理系統(Dependency Management System),和用來運行定義在生命週期階段(phase)中插件(plugin)目標(goal)的邏輯。 當你使用Maven的時候,你
用一個明肯定義的項目對象模型來描述你的項目,而後 Maven 能夠應用橫切的邏輯,這些邏輯來自一組共享的(或者自定義的)插件。java

maven安裝好後的目錄項:LICENSE.txt包含Apache Maven的許可證,NOTE.txt包含Maven依賴的類庫所須要的通告及權限。README.txt包含安裝指令,/bin目錄下是運行Maven的mvn腳本,boot/目錄下包含建立Maven運行所需的類加載器的jar文件,conf/目錄包含全局settings.xml文件,定義機器上Maven的行爲,用戶自定義行爲能夠在home目錄下.m2下複寫setting.xml文件。lib/目錄包含Maven核心Jar文件。web

在命令行使用命令 mvn archetype:create -DgroupId=,-DartifactId=,-DpackageName=。能夠生成一個簡單項目,artifactId指定了項目的名稱,項目源碼和資源文件放置在src/main目錄下,測試代碼在src/test目錄,同時還包含一個項目文件pom.xml,稱爲項目對象模型。這個文件描述了整個項目,配置了插件,聲明瞭依賴。apache

解釋下命令的含義,archetype:create是一個插件標識和一個目標標識,這裏一個插件是一個或多個目標的集合,而一個目標是一個明確的任務,是maven的一個工做單元,目標能夠經過配置屬性進行配置,定製目標的行爲,create是插件archetype的一個目標,執行這個目標時,用-D配置了目標參數。create目標定義了一個配置屬性archetypeArtifactId,默認值爲maven-archetype-quickstart,用以生成一個最小項目的軀殼,包括一個類和一個項目文件pom。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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.bruce.mu</groupId>
  <artifactId>app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>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>

從groupId開始,groupId,artifactId,version,packaging四個元素定義了一個項目的座標,即惟一標識一個項目。這個座標也是標識了一個地址,能夠寫成冒號分隔的格式:groupId:artifactId,packageing,version。packageing能夠是jar或war,jar打包成普通jar文件,而war打包成web應用。若是一個項目被安裝到maven倉庫,在倉庫中項目就按照座標保存和尋找。在pom.xml所在目錄運行命令mvn install能夠將項目安裝到maven倉庫。install是一個生命週期階段,它會把項目構建安裝到maven倉庫,以使其餘項目可以將其做爲依賴。緩存

maven運行一個項目,是根據pom中的設置來組合運行的,一個最上級的POM定義了maven的安裝目錄,定義了全局默認值,運行時多個pom組合在一塊兒,mvn help:effectiove-pom能夠查看maven運行此項目時真正的POM。app

maven的命令有兩種,一種如建立一個項目那樣,由一個插件標識,目標標識和配置參數組成,還有一種如mvn install是指定一個生命週期階段,即構建一個生命週期整個過程當中的一個環節。而生命週期是指一個項目構建過程當中所經歷的有序階段。生命週期是可定製的,但maven有默認的生命週期。maven

插件與目標能夠附着在生命週期階段上,隨着生命週期的移動,會執行附着在特定階段上的插件目標,每一個階段可能綁定多個目標,執行一個生命週期階段時,會執行從生命週期開始到該階段的全部階段,即執行這些階段上附着的全部插件目標。下圖顯示了默認生命週期階段上綁定的插件目標:ide

resources:resources
Resources插件的resources目標綁定到了resources 階段。這個目標複製src/main/resources下的全部資源和其它任何配置的資源目錄,到輸出目錄。
compiler:compile
Compiler插件的compile目標綁定到了compile 階段。這個目標編譯src/main/java下的全部源代碼和其餘任何配置的資源目錄,到輸出目錄。
resources:testResources
Resources插件的testResources目標綁定到了test-resources 階段。這個目標複製src/test/resources下的全部資源和其它任何的配置的測試資源目錄,到測試
輸出目錄。
compiler:testCompile工具

Compiler插件的testCompile目標綁定到了test-compile 階段。這個目標編譯src/test/java下的測試用例和其它任何的配置的測試資源目錄,到測試輸出
目錄。
surefire:test
Surefire插件的test目標綁定到了test 階段。這個目標運行全部的測試而且建立那些捕捉詳細測試結果的輸出文件。默認狀況下,若是有測試失敗,這個目標
會終止。測試

jar:jar
Jar插件的jar目標綁定到了package 階段。這個目標把輸出目錄打包成JAR文件。

maven倉庫:第一次運行maven時,maven將從遠程倉庫下載不少文件,構件和插件是在被須要是從遠程倉庫下載的,默認的遠程倉庫地址能夠被替換,甚至能夠自定義一個自組織的倉庫供引用。maven倉庫是一堆項目構件的集合,他們安裝特定的目錄結構存儲,而這些目錄結構是安裝項目構件的座標來組織的。maven會在本地機器上建一個本地倉庫,緩存從遠程倉庫下載的構件和插件,這個倉庫是.m2/repository.maven尋找構件是會先從本地開始尋找。

maven依賴管理:一個項目的pom文件中定義了插件依賴,如上圖pom.xml定義junit插件,是基於maven的座標定位插件的具體位置。有時候一個項目依賴的構件自己也會依賴其餘更多的構件,maven項目依賴的構件爲直接依賴,而依賴構件所依賴的構件爲此maven項目的間接依賴,pom文件中只需定義直接依賴,Maven會隱式的把間接依賴的庫也加入項目中,並處理依賴衝突。事實上當處理一個直接依賴時,maven從倉庫(先本地後遠程)下載構件,同時下載.pom文件,以junit爲例,按此junit依賴的座標,會下載junit:junit:3.8.1,其實這是一個目錄,包含一個.jar文件和一個.pom文件,.jar文件就是所需的依賴構件,而.pom文件中同時定義了此構件所需依賴的構件。maven也會檢查此pom以導入間接依賴。maven同時下載構件和pom文件的行爲支持了依賴傳遞。

maven同時提供依賴範圍,junit的依賴範圍是<scope>test</scope>,當一個依賴的範圍是test,就是說此構件只有在test類型的目標運行是纔會使用。舉例來講,在complier插件的complie目標運行時不會使用,而當complier:testComplie,surefire:test時會被加入classpath。

當爲項目建立JAR文件的時候,它的依賴不會被捆綁在生成的構件中,他們只是用來編譯。當用Maven來建立WAR或者EAR,你能夠配置Maven讓它在生成的構件中捆綁依賴,你也能夠配置Maven,使用provided範圍,讓它排除WAR文件中特定的依賴。provided範圍告訴Maven一個依賴在編譯的時候須要,可是它不該該被捆綁在構建的輸出中。當你開發web應用的時候provided範圍變得十分有用,你須要經過Servlet API來編譯你的代碼,可是你不但願Servlet API的JAR文件包含在你web應用的WEB-INF/lib目錄中。