Maven的pom.xml文件簡稱POM (Project Object Model),是Maven項目的配置和管理核心。
一個簡單的pom解析
<?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
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<name> MAVEN Hello World Project</name>
</project>
代碼的第一行是XML頭,指定了xml文檔的版本和編碼格式。
project元素是所有pom.xml的根元素,它聲明瞭一些POM相關的命名空間及xsd元素,雖然這些屬性不是必須的,但使用這些屬性可以讓第三方工具(如IDE中的XML編輯器)幫助我們快速的編輯pom.
根元素下的第一個元素modelVersion指定了當前POM的版本,對於Maven 2 及 Maven 3來說,它只能是4.0.0。
name元素聲明瞭一個對於用戶更友好的項目名稱,這不是必須的,聲明名稱,便於交流。
maven座標
<groupId>org.apache</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<package>jar</package>
groupId:定義當前Maven項目隸屬的實際項目。
artifactId:定義實際項目中的一個Maven項目(模塊),推薦的做法是使用實際項目名稱作爲artifactId的前綴。
version:定義Maven項目當前所處的版本。
packaging:定義Maven項目的打包方式。
完整的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/maven-v4_0_0.xsd ">
<!-- 父項目的座標。如果項目中沒有規定某個元素的值,那麼父項目中的對應值即爲項目的默認值。
座標包括group ID,artifact ID和 version。 -->
<parent>
<!-- 被繼承的父項目的構件標識符 -->
<artifactId>xxx</artifactId>
<!-- 被繼承的父項目的全球唯一標識符 -->
<groupId>xxx</groupId>
<!-- 被繼承的父項目的版本 -->
<version>xxx</version>
<!-- 父項目的pom.xml文件的相對路徑。相對路徑允許你選擇一個不同的路徑。默認值是../pom.xml。
Maven首先在構建當前項目的地方尋找父項目的pom,其次在文件系統的這個位置(relativePath位置),
然後在本地倉庫,最後在遠程倉庫尋找父項目的pom。 -->
<relativePath>xxx</relativePath>
</parent>
<!-- 聲明項目描述符遵循哪一個POM模型版本。模型本身的版本很少改變,雖然如此,但它仍然是必不可少的,
這是爲了當Maven引入了新的特性或者其他模型變更的時候,確保穩定性。 -->
<modelVersion> 4.0.0 </modelVersion>
<!-- 項目的全球唯一標識符,通常使用全限定的包名區分該項目和其他項目。並且構建時生成的路徑也是由此生成,
如com.mycompany.app生成的相對路徑爲:/com/mycompany/app -->
<groupId>xxx</groupId>
<!-- 構件的標識符,它和group ID一起唯一標識一個構件。換句話說,你不能有兩個不同的項目擁有同樣的artifact ID
和groupID;在某個特定的group ID下,artifact ID也必須是唯一的。構件是項目產生的或使用的一個東西,Maven
爲項目產生的構件包括:JARs,源碼,二進制發佈和WARs等。 -->
<artifactId>xxx</artifactId>
<!-- 項目產生的構件類型,例如jar、war、ear、pom。插件可以創建他們自己的構件類型,所以前面列的不是全部構件類型 -->
<packaging> jar </packaging>
<!-- 項目當前版本,格式爲:主版本.次版本.增量版本-限定版本號 -->
<version> 1.0-SNAPSHOT </version>
<!-- 項目的名稱, Maven產生的文檔用 -->
<name> xxx-maven </name>
<!-- 項目主頁的URL, Maven產生的文檔用 -->
<url> http://maven.apache.org </url>
<!-- 項目的詳細描述, Maven 產生的文檔用。 當這個元素能夠用HTML格式描述時(例如,CDATA中的文本會被解析器忽略,
就可以包含HTML標籤), 不鼓勵使用純文本描述。如果你需要修改產生的web站點的索引頁面,你應該修改你自己的
索引頁文件,而不是調整這裏的文檔。 -->
<description> A maven project to study maven. </description>
<!-- 項目創建年份,4位數字。當產生版權信息時需要使用這個值。 -->
<inceptionYear />
<!-- 模塊(有時稱作子項目) 被構建成項目的一部分。列出的每個模塊元素是指向該模塊的目錄的相對路徑 -->
<modules>
<!--子項目相對路徑-->
<module></module>
</modules>
<!-- 繼承自該項目的所有子項目的默認依賴信息。這部分的依賴信息不會被立即解析,而是當子項目聲明一個依賴
(必須描述group ID和artifact ID信息),如果group ID和artifact ID以外的一些信息沒有描述,則通過
group ID和artifact ID匹配到這裏的依賴,並使用這裏的依賴信息。 -->
<dependencyManagement>
......
</dependencyManagement>
<!-- 構建項目需要的信息 -->
<build>
......
</build>
<!-- 發現依賴和擴展的遠程倉庫列表。 -->
<repositories>
......
</repositories>
<!-- 在列的項目構建profile,如果被激活,會修改構建處理 -->
<profiles>
......
</profiles>
<!-- 發現插件的遠程倉庫列表,這些插件用於構建和報表 -->
<pluginRepositories>
......
</pluginRepositories>
<!-- 該元素描述了項目相關的所有依賴。 這些依賴組成了項目構建過程中的一個個環節。它們自動從項目定義的倉庫中下載。
要獲取更多信息,請看項目依賴機制。 -->
<dependencies>
......
</dependencies>
<!-- 該元素描述使用報表插件產生報表的規範。當用戶執行“mvn site”,這些報表就會運行。 在頁面導航欄能看到所有報表的鏈接。 -->
<reporting>
......
</reporting>
<!-- 項目分發信息,在執行mvn deploy後表示要發佈的位置。有了這些信息就可以把網站部署到遠程服務器或者
把構件部署到遠程倉庫。 -->
<distributionManagement>
......
</distributionManagement>
<!-- 以值替代名稱,Properties可以在整個POM中使用,也可以作爲觸發條件(見settings.xml配置文件裏
activation元素的說明)。格式是<name>value</name>。 -->
<properties>
<name>value</name>
</properties>
</project>
模塊化-models
Maven Module也是一個maven 工程,但是卻是一個子工程,必須有父工程存在並依賴,Maven Module不能拋棄父工程單獨存在。
Maven Project可以理解爲一個單獨、獨立的工程,在打包爲jar或者war時,可以單獨運行。如果在pom文件中添加了對父工程的依賴,此時作爲父工程的子工程。
<modules>
<module>microservicecloud-api</module>
<module>microservicecloud-provider-dept-8001</module>
</modules>
因爲有該節點存在,所以在父工程使用命令run as Maven install
將會把父工程與所有子工程都打包安裝到本地倉庫。
依賴的配置-dependency
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>2.0.0</version>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>
...
</exclusion>
</exclusions>
<dependency>
- groupId、artifactId和version:依賴的基本座標
- type:依賴的類型,對應於項目座標定義的packaging
-
scope:依賴的範圍:scope的取值有compile、runtime、test、provided、system和import。
-
optional:標記依賴是否可選。
使用場景:可能B項目實現了兩個特性,其中的特性一依賴與X,特性二依賴與Y,而這兩個特性是互斥的,用戶不可能同時使用兩個特性。比如B是一個持久層隔離工具包,它支持多種數據庫,包括MySQL、PostgreSQL等,在構建這個工具包的時候,需要這兩種數據庫的驅動程序,但在使用這個工具包的時候,只會依賴一種數據庫。 -
exclusions:用來排除傳遞性依賴。
依賴的管理-dependencyManagement
dependencyManagement主要有兩個作用,一個是集中管理項目的依賴項,另一個就是控制使用的依賴項的版本。
profiles
在開發過程中,我們的項目會存在不同的運行環境,比如開發環境、測試環境、生產環境,而我們的項目在不同的環境中,有的配置可能會不一樣,比如數據源配置、日誌文件配置、以及一些軟件運行過程中的基本配置,那每次我們將軟件部署到不同的環境時,都需要修改相應的配置文件,這樣來回修改,很容易出錯,而且浪費勞動力。
在前面的文章profile之springboot,springboot爲我們提供了一種解決方案,而maven也提供了一種更加靈活的解決方案,就是profile功能。
<profiles>
<profile>
<!--不同環境Profile的唯一id-->
<id>dev</id>
<properties>
<!--profiles.active是自定義的字段(名字隨便起),自定義字段可以有多個-->
<profiles.active>dev</profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
</profiles>
可以看到定義了多個profile,每個profile都有唯一的id,也包含properties屬性。這裏爲每個profile都定義一個名爲profiles.active的properties,每個環境的值不同。當我們打包項目時,激活不同的環境,profiles.active字段就會被賦予不同的值。
這個profiles.active字段可以應用到許多地方,及其靈活。可以在配置文件裏被引用;也可以結合pom文件裏的resource和filter屬性,作爲文件名的一部分或者文件夾名的一部分。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources/</directory>
<!--打包時先排除掉三個文件夾-->
<excludes>
<exclude>dev/*</exclude>
<exclude>prod/*</exclude>
<exclude>test/*</exclude>
</excludes>
<includes>
<!--如果有其他定義通用文件,需要包含進來-->
<!--<include>messages/*</include>-->
</includes>
</resource>
<resource>
<!--這裏是關鍵! 根據不同的環境,把對應文件夾裏的配置文件打包-->
<directory>src/main/resources/${profiles.active}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<!--不同環境Profile的唯一id-->
<id>dev</id>
<properties>
<!--profiles.active是自定義的字段,自定義字段可以有多個-->
<profiles.active>dev</profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
<!--activation用來指定激活方式,可以根據jdk環境,環境變量,文件的存在或缺失-->
<activation>
<!--這個字段表示默認激活-->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
</profiles>
激活方式
- 通過maven命令參數:mvn clean package -Ptest
- 通過pom文件裏的activation屬性
-
settings.xml中使用activeProfiles指定
構建部分-build
pom中一大部分配置都包含在build標籤中,這部分是在對項目進行構建時所需要的配置,當你對項目進行編譯,測試,打包,發佈的時候,這部分配置就會在對應的階段起作用了。
build標籤中可以包含很多插件,這些插件可以配置到項目的某些構建階段,隨着項目的構建進程發揮作用。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.fox</groupId>
<artifactId>demo</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
報表部分-reporting
我們執行mvn site就可以爲項目生成一系列可以用來描述項目信息的網頁,maven2中的一大部分插件就是專門在這時候發揮效用的,它們可以根據項目的結構,源代碼,測試,SCM信息等,生成各種特殊功能的報表,這要把這些插件配置在reporting標籤中,它們就會在執行mvn site的同時起作用。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.fox</groupId>
<artifactId>demo</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
</reporting>
</project>
環境配置
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<distributionManagement>...</distributionManagement>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<profiles>...</profiles>
說明:
issueManagement,給出defect tracking system及其訪問URL
- system
- url
ciManagement,給出Continuous Integration Management、其URL和notifier
- system
- url
- notifiers,集成過程中發生事件,以某種方式(如mail)通知開發人員
scm,software configuration management
- connection,用戶使用的URI,能夠只讀地訪問版本控制系統
- developerConnection,開發人員使用URI,能夠讀寫地訪問版本控制系統
- tag,項目當前的tag
- url,可通過Web瀏覽器訪問的公共網址
distributionManagement,構件的發佈管理
prerequisites,POM執行的前提條件,目前只支持對Maven版本的要求
- maven
mailingLists,開發人員或用戶的郵件列表
--mailingList
- name
- subscribe,訂閱地址
- unsubscribe,取消訂閱地址
- post,POST郵件的目的地址
- archive,打包的郵件列表歷史記錄
- otherArchives,鏡像打包的郵件列表歷史記錄
其他信息
name,項目的名稱代號
description,項目的說明
url,項目的官網URL
inceptionYear,項目的開發年份
licenses,項目使用的License。其中可以包含多個license,license具體又包含如下子屬性
- name,license的名稱
- url,license可訪問的URL地址
- distribution,license發佈的方式。repo表示可以直接從Maven庫下載,manual表示必須手工安裝
- comments,對license的說明
organization,包含組織的name,組織的官網url
developers,其中的developer包含id, name, email, url, organization, organizationUrl, roles, timezone, properties屬性
- properties是可以自定義的各種必要屬性
contributors,其中的contributor包含與developer基本相同的屬性,除了沒有id屬性之外