Maven項目依賴,構建配置,以及構建,全部這些都是要建模和表述的對象。這些對象經過一個名爲項目對象模型(POM)的XML文件描述。java
如圖2sql
圖2shell
POM包含了四類描述和配置:apache
§項目整體信息api
包含一個項目的名稱,項目的URL,發起組織,以及項目的開發者,貢獻者列表和許可證。maven
§構建設置ide
可自定義Maven構建的默認行爲,更改源碼和測試代碼的位置,能夠添加新的插件,能夠將插件目標綁定到生命週期,能夠自定義站點生成參數。佈局
§構建環境測試
構建環境包含了一下能在不一樣環境中使用激活的profile。ui
§POM關係
定義自身的座標。依賴於其餘項目。包含子模塊。
超級POM,全部的項目都依賴於超級POM,超級POM是最基礎的。超級POM定義了一組被全部項目共享的默認設置,位置是\apache-maven-3.0.5\lib 下的 maven-model-builder-3.0.5.jar 中的 org/apache/maven/model/pom-4.0.0.xml
注意超級POM關閉了從中央Maven倉庫下載snapshot構建功能。
Maven開始於超級POM,而後使用一個或多個父POM覆蓋默認配置,最後使用當前項目的POM來覆蓋以前生成的配置結果。查看當前項目依賴的命令:mvn help:effective-pom。
最簡單的POM
<project> <modelVersion>4.0.0</modelVersion> <groupId>org.sonatype.mavenbook.ch08</groupId> <artifactId>simplest-project</artifactId> <version>1</version> </project>
Maven項目中的POM永遠都是基礎目錄下的一個名爲pom.xml的文件。
Maven項目發佈版本號使用version編碼。Maven的版本包括:主版本,次版本,增量版本,和限定版本。格式以下<major version>.<minor version>.<incremental version>-<qualifier>。限定版本用來標識里程碑構建:alpha和beta發佈。限定版本經過連字符與主版本,次版本或增量版本隔離。例如:版本」1.3-beta-01「有一個主版本1,次版本3,和一個限定版本「beta-01」。
注意:Maven被設計成將構建版本和限定版本分離,但目前這種解析仍是失敗的。如:"alpha-2"和"alpha-10" 是用字符串進行比較的。這樣"alpha-10"比"alpha-2"更舊。解決方法:定義爲"alpha-02"和"alpha-10",就可避免此類問題的出現。
§SNAPSHOT版本
Maven版本能夠包含一個字符串字面量來表示項目正處於活動開發狀態。若是一個版本包含字符串"SNAPSHOT",Maven就會在安裝或者發佈這個組件的時候將該符號展開爲一個日期和時間值,轉換爲UTC。當你發佈一個snapshot,只是發佈了一個特定時間的快照版本。在構建的時候Maven會按期的從倉庫中下載最新的snapshot。
§LATEST和RELEASE版本
LATEST是指構建最新的發佈版或快照版。RELEASE是指倉庫中最後的一個非快照版本。當依賴於一個插件或一個依賴時,可使用特殊的版本值LATEST或者RELEASE。
一個POM能夠經過${}來包含對屬性的引用,在Mavne讀取POM的時候,他會在載入POM的時候替換這些屬性引用。
§ env變量:操做系統或者shell的環境變量;
§project:POM的project屬性,使用點標記的路徑來引用POM元素的值;
§settings:引用Maven settings信息,使用點標記來引用settings.xml文件中元素的值;
§Java系統屬性:因此能夠經過java.lang.System中的getProperties()方法訪問的屬性能夠成爲POM屬性,如${user.name},${user.home},${java.home}和${os.home};
§還能夠經過Pom.xml或者setting.xml中的properties元素設置本身的屬性,或者還可使用外部載入的文件中屬性。
Maven能夠管理內部和外部依賴。
Maven座標爲各類構建引入了秩序,任何一個構建都必須有明肯定義本身的座標,而一組Maven座標是經過一些元素定義的。
以下:
<project> <groupId>org.sonatypr.nexus</groupId> <artifactId>nexus-index</artifactId> <version>2.0.0</version> <packaging>jar</packaging> </project>
groupId:定義當前Maven項目隸屬的實際項目。Maven項目和實際項目不必定是一對一的關係。一個實際項目每每會被劃分紅不少模塊,因此groupId通常都定義與實際項目對應。表示方法與Java包名的表示方法相同。
artifactId:該元素定義實際項目中的一個Maven項目(模塊)。推薦作法是使用實際項目名稱爲artifactId的前綴。這樣的好處在於方便從一個lib文件夾中找到某個項目的一組構建。
version:該元素定義Maven項目當前所處的版本。
packaging:該元素定義Maven項目的打包方式。首先,打包方式一般與所生成構件的文件擴展名對應。其次,打包方式會影響到構建的生命週期。例如jar打包和war打包會使用不一樣的命令。
classifiler:該元素用來幫助定義構建輸出的一些附屬構件。例如Jave文檔和源碼。
只要提過正確的座標元素,Maven就能找到對應的構件。項目構件的文件名是與座標對應的,通常規則爲artifactId-version[-calssifier].packaging。
Maven倉庫佈局也是基於Maven座標的。
<project> ... <dependencies> <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <type>...</type> <scope>...</scope> <optional>...</optional> <exclusions> <exclusion> ... </exclusion> <exclusion> ... </exclusion> </exclusions> </dependency> </dependencies> </project>
根元素project下的dependencies能夠包含一個或者多個dependency元素,以生命一個或者多個項目依賴。每一個依賴能夠包含的元素有:
groupId,artifactId,version:依賴的基本座標,對於任何一個項目依賴來講,基本座標是最重要的,Maven根據座標才能找到需求的依賴。
type:依賴類型,對應於項目座標定義的packaging。大部分狀況下,該元素沒必要生命,其默認值爲jar。
scope:依賴範圍。
optional:標記依賴是否可選。
exclusions:用來排除傳遞性依賴。
注意Maven在編譯,測試,運行時會個使用一套classpath。
依賴範圍是用來控制依賴與這三種classpath(編譯classpath,測試classpath,運行classpath)的關係。Maven有如下幾種依賴範圍:
§compile:編譯依賴範圍。compile是默認的範圍:若是沒提供一個範圍,那該依賴的範圍就是編譯範圍。使用此以來範圍的Maven依賴,對於編譯,測試,運行三種classpath都有效。
§test:測試依賴範圍。使用此依賴範圍的Maven依賴,只對於測試的classpath有效,在編譯主代碼或者運行項目的使用時將沒法使用此類依賴,典型的例子是JUnit。
§provided:已提供依賴範圍。使用此依賴範圍的Maven依賴,對於編譯和測試的classpath有效,但在運行時無效。典型的例子是servlet-api,編譯和測試項目的時候須要改依賴,但在運行項目的時候,因爲容器已經提供,就不須要Maven從新引入。
§runtime:運行時依賴範圍。使用此依賴範圍的Maven依賴,對於測試和運行classpath有效,但在編譯主代碼是無效。典型的例之就是JDBC驅動實現,項目主代碼的編譯只須要JDK提供的JDBC接口。
§system:系統依賴範圍。該依賴與三種classpath的關係,和provided依賴範圍徹底一致。可是,使用system範圍依賴時必須經過systemPath元素顯示地制定依賴文件的路徑。必須顯示的提供一個對於本地系統中JRA文件路徑。因爲此類依賴不是經過Maven倉庫解析的,並且每每與本機系統綁定,可能形成構建的不可移植,所以應該謹慎使用。如:
<dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-stdext</artifactId> <version>2.0</version> <scope>system</scope> <systempath>${java.home}/lib/rt.jar</systempath. </dependency>
§import(Maven2.0.9及以上):導入依賴範圍。該依賴範圍不會對三種classpath產生實際的影響。該依賴只在dependencyManagement元素下才有效果,使用該範圍的依賴一般指向一個POM,做爲是經目標POM中的dependencyManagement配置導入併合併到當前POM的dependencyManagement元素中。
<dependencyManagement> <dependencies> <dependency> <groupId>com.sun.pro</groupId> <artifactId>jpro-action</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
注:上述代碼中依賴的type值爲pom,import範圍依賴因爲其特殊性,通常都是指向打包類型爲pom的模塊。若是多個項目,它們使用依賴版本都是一致的,則就能夠定義一個使用dependencyManagement專門管理依賴的POM,而後在各個項目中導入這些依賴管理配置。