POM 代表“Project Object Model”霜大。它是 Maven 項(xiàng)目的 XML 表示形式,保存在名為 pom.XML 的文件中纹腌。一個(gè)項(xiàng)目不僅僅是包含代碼的文件集合材原,還包含配置文件,以及所涉及的開發(fā)人員和他們扮演的角色、缺陷跟蹤系統(tǒng)、組織和許可證、項(xiàng)目所在地的 URL均澳、項(xiàng)目的依賴關(guān)系,以及所有其他為賦予代碼生命而發(fā)揮作用的小部分符衔。事實(shí)上找前,在 Maven 世界中,項(xiàng)目根本不需要包含任何代碼判族,只需要一個(gè) pom.xml
躺盛。
下面是 pom.xml 文件中的元素列表。請(qǐng)注意五嫂,modelVersion
必須為 4.0.0
颗品。這是當(dāng)前唯一受支持的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- The Basics -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- Build Settings -->
<build>...</build>
<reporting>...</reporting>
<!-- More Project Information -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
POM 包含關(guān)于項(xiàng)目的所有必要信息躯枢,以及構(gòu)建過程中使用的插件配置。它是“who”槐臀、“what”和“where”的聲明性表示锄蹂,而構(gòu)建生命周期是“when”和“how”。這并不是說 POM 不能影響生命周期的流程——它可以水慨。例如得糜,通過配置 maven-antrun-plugin
插件,可以將 Apache Ant 任務(wù)嵌入 POM 中晰洒。然而朝抖,這最終是一個(gè)聲明。雖然 Ant 的 build.xml
精確地告訴 Ant 在運(yùn)行時(shí)要做什么谍珊,但 POM 聲明了它的配置治宣。如果某些外力導(dǎo)致生命周期跳過 Ant 插件的執(zhí)行,它不會(huì)阻止其他插件的執(zhí)行砌滞。這與 build.xml
文件不同侮邀,在 build.xml
文件中,任務(wù)幾乎總是依賴于它之前執(zhí)行的行贝润。
Maven 坐標(biāo)
上面定義的 POM 是 Maven 允許的最小值绊茧。Maven 中的坐標(biāo)元素必須包含 groupId
、artifactId
打掘、version
华畏。如果 groupId
和 version
是從其父級(jí)繼承的鹏秋,則不需要顯式定義。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
</project>
-
groupId
:該元素定義當(dāng)前 Maven 項(xiàng)目所隸屬的實(shí)際項(xiàng)目亡笑,在一個(gè)實(shí)際項(xiàng)目中通常是獨(dú)一無(wú)二的拼岳。首先,Maven 項(xiàng)目和實(shí)際項(xiàng)目不一定是一對(duì)一的關(guān)系况芒。比如 SpringFramework 這一實(shí)際項(xiàng)目,其下對(duì)應(yīng)的 Maven 項(xiàng)目會(huì)有很多叶撒,如 spring-core绝骚、spring-context 等。這是由于 Maven 中模塊的概念祠够,因此压汪,一個(gè)實(shí)際項(xiàng)目往往會(huì)被劃分成很多模塊。
groupId
不應(yīng)該對(duì)應(yīng) Maven 項(xiàng)目所隸屬的組織機(jī)構(gòu)或公司古瓤。原因很簡(jiǎn)單止剖,一個(gè)組織機(jī)構(gòu)或公司下會(huì)有很多實(shí)際項(xiàng)目,如果groupld
只定義到組織機(jī)構(gòu)或公司級(jí)別落君,那么artifactld
只能定義實(shí)際項(xiàng)目級(jí)別穿香,那么 Maven 項(xiàng)目級(jí)別(模塊)這個(gè)層次將難以定義;其次绎速,
groupId
不一定使用點(diǎn)號(hào)表示法皮获,例如 junit 項(xiàng)目。請(qǐng)注意纹冤,以點(diǎn)號(hào)表示的groupId
不必與項(xiàng)目包含的包結(jié)構(gòu)相對(duì)應(yīng)洒宝。然而,這是一個(gè)值得遵循的良好實(shí)踐萌京。最后雁歌,
groupld
的表示方式與 Java 包名的表示方式類似,通常與倒序的域名一一對(duì)應(yīng)知残。上例中靠瞎,groupld
為 org.sonatype.nexus,org.sonatype 表示 Sonatype 公司建立的一個(gè)非盈利性組織橡庞,nexus 表示Nexus 這一實(shí)際項(xiàng)目较坛,該 groupId 與倒序的 nexus.sonatype.org 域名對(duì)應(yīng)。當(dāng)存儲(chǔ)在倉(cāng)庫(kù)中時(shí)扒最,groupId
中的點(diǎn)號(hào)被特定于操作系統(tǒng)的目錄分隔符(如 Unix 中的/
)所取代丑勤,該分隔符將成為倉(cāng)庫(kù)基準(zhǔn)目錄下的相對(duì)目錄結(jié)構(gòu)。例如吧趣,org.sonatype.nexus 組位于倉(cāng)庫(kù)中的$M2_REPO/org/sonatype/nexus
目錄中法竞。 artifactId
:該元素定義實(shí)際項(xiàng)目中的一個(gè) Maven 項(xiàng)目(模塊)耙厚,推薦的做法是使用實(shí)際項(xiàng)目名作為artifactId
的前綴。比如上例中的artifactId
是nexus-indexer
, 使用了實(shí)際項(xiàng)目名 nexus 作為前綴岔霸,這樣做的好處是方便尋找實(shí)際工件薛躬。在默認(rèn)情況下,Maven 生成的工件呆细,其文件名會(huì)以artifactId
作為開頭型宝,如 nexus-indexer-2. 0.0.jar,使用實(shí)際項(xiàng)目名稱作為前綴之后絮爷,就能方便從一個(gè) lib 文件夾中找到某個(gè)項(xiàng)目的一組構(gòu)件趴酣。考慮有 5 個(gè)項(xiàng)目坑夯,每個(gè)項(xiàng)目都有一個(gè)core模塊岖寞,如果沒有前綴,我們會(huì)看到很多 core-1.2. jar 這樣的文件柜蜈,加上實(shí)際項(xiàng)目名前綴之后仗谆,便能很容易區(qū)分 foo-core-1.2.jar、bar-core-1.2.jar 等淑履。artifactId
完全定義了工件在倉(cāng)庫(kù)中的存儲(chǔ)位置隶垮。上述的項(xiàng)目位于倉(cāng)庫(kù)中的$M2_REPO/org/sonatype/nexus/nexus-indexer
目錄中。version
:該元素定義 Maven 項(xiàng)目當(dāng)前所處的版本鳖谈,如上例中 nexus-indexer 的版本是 2.0.0岁疼。 需要注意的是,Maven 定義了一套完成的版本規(guī)范捷绒,以及快照(SNAPSHOT)的概念。version
還用于將倉(cāng)庫(kù)中的某個(gè)工件各版本分離開來鸠信,例如琳袄,上述項(xiàng)目 2.0.0 版本的工件位于倉(cāng)庫(kù)中的$M2_REPO/org/sonatype/nexus/nexus-indexer
目錄中秃嗜。
現(xiàn)在我們有了 groupId:artifactId:version
的地址結(jié)構(gòu)取劫,還有一個(gè)標(biāo)準(zhǔn)的 packaging
元素用來定義 Maven 項(xiàng)目的打包類型迅栅。當(dāng)未聲明任何打包類型時(shí)殊校,Maven 假定的默認(rèn)打包類型為 jar
。該元素當(dāng)前支持的值有:pom
读存、jar
为流、maven-plugin
、ejb
让簿、war
敬察、ear
、rar
尔当。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<packaging>war</packaging>
...
</project>
依賴
POM 的基石是其依賴項(xiàng)列表莲祸。大多數(shù)項(xiàng)目依賴其他項(xiàng)目來正確地構(gòu)建和運(yùn)行。在編譯時(shí)或執(zhí)行其他需要需要這些依賴項(xiàng)的目標(biāo)時(shí)椭迎,Maven 會(huì)下載并鏈接這些依賴項(xiàng)锐帜。作為額外的好處,Maven 會(huì)引入這些依賴項(xiàng)的依賴項(xiàng)(即使沒有顯式聲明)畜号,可傳遞依賴項(xiàng)抹估,允許您的列表只關(guān)注項(xiàng)目所需的依賴項(xiàng)。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<classifier>jar</classifier>
<type>jar</type>
<scope>test</scope>
<systemPath>test</systemPath>
<optional>true</optional>
</dependency>
...
</dependencies>
...
</project>
-
groupId
弄兜、artifactId
药蜻、version
:該三個(gè)元素用于計(jì)算特定項(xiàng)目的 Maven 坐標(biāo),并將其當(dāng)作為該項(xiàng)目的依賴項(xiàng)替饿。由于可傳遞的依賴項(xiàng)语泽,同一工件可以有多個(gè)依賴項(xiàng)聲明。由于依賴關(guān)系由 Maven 坐標(biāo)描述视卢,這意味著當(dāng)前項(xiàng)目只能依賴 Maven 的依賴項(xiàng)來管理工件及其依賴關(guān)系踱卵。不幸的是,有時(shí)無(wú)法從 Maven 中央倉(cāng)庫(kù)下載項(xiàng)目。例如惋砂,一個(gè)項(xiàng)目可能依賴于一個(gè)擁有封閉源代碼許可的 jar妒挎,該許可不允許它上傳到中央存儲(chǔ)庫(kù)中。有三種方法可以處理這種情況西饵。-
使用
maven-install-plugin
插件的install:install-file
目標(biāo)來將擁有封閉源代碼許可的 jar 安裝到本地倉(cāng)庫(kù)中酝掩。例如:mvn install:install-file -Dfile=D:\JavaDev\myapp.jar -DgroupId=com.myapp -DartifactId=myapp-core -Dversion=1.0.0 -Dpackaging=jar
使用
maven-deploy-plugin
插件的deploy:deploy-file
的目標(biāo)來該擁有封閉源代碼許可的 jar 文件部署到您私有的 Maven 倉(cāng)庫(kù)中。這樣眷柔,所以可以連接到該倉(cāng)庫(kù)的開發(fā)電腦都可以像使用正常依賴那樣使用該依賴了期虾。將依賴項(xiàng)的
scope
子元素值設(shè)置為system
并定義一個(gè)同級(jí)的systemPath
子元素,然后指定systemPath
子元素的值為該擁有封閉源代碼許可的 jar 文件的本地路徑驯嘱。但是镶苞,不建議這樣做。
-
classifier
:該元素用來幫助定義構(gòu)建輸出的一些附屬構(gòu)件鞠评。它是一些可選的任意字符串茂蚓,如果存在的話,會(huì)被附加到版本號(hào)后面的工件名稱上剃幌。如上例中的主構(gòu)件是 nexus-indexer-2.0.0.jar煌贴,該項(xiàng)目可能還會(huì)通過使用一些插件生成如 nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar 這樣的一些附屬構(gòu)件锥忿,其包含了 Java 文檔和源代碼。這時(shí)候怠肋,javadoc 和 sources 就是這兩個(gè)附屬構(gòu)件的 classifier敬鬓。 這樣,附屬構(gòu)件也就擁有了自己唯一的坐標(biāo)笙各《ご穑考慮這樣一個(gè)項(xiàng)目,它提供了一個(gè)針對(duì) Java 11 的工件杈抢,但同時(shí)也是一個(gè)仍然支持 Java 1.8 的工件数尿。第一個(gè)工件可以指定classifier
值為 jdk11,第二個(gè)工件可以指定classifier
值為 jdk8惶楼,這樣用戶就可以根據(jù)需要選擇使用哪一個(gè)右蹦。注意,不能直接定義項(xiàng)目的classifier
, 因?yàn)楦綄贅?gòu)件不是項(xiàng)目直接默認(rèn)生成的歼捐,而是由附加的插件幫助生成何陆。-
type
:指定所選依賴項(xiàng)的類型,大部分情況下不需要聲明該元素豹储,默認(rèn)為jar
贷盲。雖然它通常表示依賴項(xiàng)文件名上的擴(kuò)展名,但情況并非總是這樣:類型可以映射到不同的擴(kuò)展名和classifier
剥扣。類型通常與依賴項(xiàng)所的packaging
元素值相對(duì)應(yīng)巩剖,盡管情況并非總是如此铝穷。新類型可以由將extensions
設(shè)置為 true 的插件來定義,因此佳魔,下面的列表這不是一個(gè)完整的列表曙聂。工件處理程序?yàn)楣ぜ系拿總€(gè)依賴類型定義信息(classifier
、extension
吃引、language
)以及如何管理該依賴項(xiàng)(添加到類路徑筹陵,包含到依賴中)。某些工件處理程序默認(rèn)在META-INF/plexus/artifact-handlers.xml
中配置:type classifier extension packaging language added to classpath includesDependencies pom
= type = type none jar
= type = type java true
test-jar
tests
jar
jar
java true
maven-plugin
jar
= type java true
ejb
jar
= type java true
ejb-client
client
jar
ejb
java true
war
= type = type java true
ear
= type = type java true
rar
= type = type java true
java-source
sources
jar
= type java javadoc
javadoc
jar
= type java true
-
scope
:此元素指定該依賴項(xiàng)的作用范圍镊尺,以及如何限制該依賴項(xiàng)的可傳遞性朦佩。Maven 在編譯項(xiàng)目主代碼時(shí)需要使用一套compile
的類路徑,Maven 在編譯和執(zhí)行測(cè)試的時(shí)候會(huì)使用一套test
的類路徑庐氮。實(shí)際運(yùn)行 Maven 項(xiàng)目的時(shí)候语稠,又會(huì)使用runtime
類路徑。有五個(gè)可用范圍:-
compile
:這是默認(rèn)的范圍弄砍,在未指定任何范圍時(shí)使用仙畦。該作用范圍的依賴項(xiàng)在compile
、test
音婶、runtime
等所有類路徑中都可用慨畸。 -
provided
:此范圍與compile
范圍非常相似,但它表示依賴項(xiàng)僅在compile
和test
類路徑上可用衣式,在runtime
類路徑不可用寸士。典型的就是 servlet-api 依賴項(xiàng),如果將該依賴項(xiàng)的scope
設(shè)置為provided
碴卧,那么弱卡,該依賴在本地編譯和測(cè)試時(shí)可以使用該依賴項(xiàng),但運(yùn)行時(shí)會(huì)選擇使用 Tomcat 或 Jetty 等 Web 容器中的 servlet-api jar 包住册。 -
runtime
:此范圍表示依賴項(xiàng)在test
婶博、runtime
類路徑下可用,但在compile
類路徑時(shí)不可用荧飞。典型的就是 JDBC 驅(qū)動(dòng)實(shí)現(xiàn)凡人,項(xiàng)目主代碼編譯時(shí)只需要 JDK 提供的 JDBC 接口,只有在執(zhí)行測(cè)試或者運(yùn)行項(xiàng)目的才用到實(shí)現(xiàn) JDBC 接口的驅(qū)動(dòng)實(shí)現(xiàn)叹阔。 -
test
:此范圍表示該依賴項(xiàng)僅在test
類路徑下可用划栓。比如 Junit、TestNG条获、spring-boot-starter-test 等用作測(cè)試的依賴項(xiàng)僅在編譯測(cè)試代碼和運(yùn)行測(cè)試的時(shí)候才需要忠荞。 -
system
:此范圍與provided
的范圍一致。使用該范圍的依賴項(xiàng)必須配合systemPath
元素一起使用。
-
systemPath
:該元素值指定本地 jar 文件的路徑委煤。僅當(dāng)scope
元素值為system
時(shí)才使用該元素拾因,否則衔肢,如果設(shè)置了該元素咒锻,則會(huì)導(dǎo)致構(gòu)建失敗比规。路徑必須是絕對(duì)路徑,因此建議使用 property 指定特定于計(jì)算機(jī)的路徑讥邻,例如${java.home}/lib
迫靖。Maven 不會(huì)去倉(cāng)庫(kù)中檢查該依賴項(xiàng),而是會(huì)根據(jù)該元素值的路徑以確保文件存在兴使。如果不存在系宜,Maven 將使構(gòu)建失敗,并建議您手動(dòng)下載并安裝它发魄。optional
:當(dāng)此項(xiàng)目本身是依賴項(xiàng)時(shí)盹牧,將依賴項(xiàng)標(biāo)記為可選的。例如励幼,假設(shè)一個(gè)項(xiàng)目 A 依賴于項(xiàng)目 B 來編譯運(yùn)行時(shí)可能不使用的部分代碼汰寓,那么我們可能不需要對(duì)所有項(xiàng)目都使用項(xiàng)目 B。所以苹粟,如果項(xiàng)目 X 將項(xiàng)目 A 添加為它自己的依賴項(xiàng)有滑,那么,Maven 根本不需要安裝項(xiàng)目 B嵌削。假如用符號(hào)表示毛好,如果if=>
表示一個(gè)必需的依賴項(xiàng),-->
表示可選的依賴項(xiàng)掷贾,盡管構(gòu)建項(xiàng)目 A 時(shí)的情況可能為A=>B
,構(gòu)建項(xiàng)目 X 的情況則為X=>A-->B
荣茫。optional
范圍可以讓其他項(xiàng)目知道想帅,當(dāng)您使用該依賴時(shí),不一定非得需要該依賴項(xiàng)才能正常工作啡莉。
依賴解析規(guī)則
Maven 引人的傳遞性依賴機(jī)制港准,一方面大大簡(jiǎn)化和方便了依賴聲明,另一方面咧欣,大部分情況下我們只需要關(guān)心項(xiàng)目的直接依賴是什么浅缸,而不用考慮這些直接依賴會(huì)引入什么傳遞性依賴。但有時(shí)候魄咕,當(dāng)傳遞性依賴造成問題的時(shí)候衩椒,我們就需要清楚地知道該傳遞性依賴是從哪條依賴路徑引入的。
例如,項(xiàng)目 A 有這樣的依賴關(guān)系: A->B->C->X(1.0)毛萌,A->D->X(2.0)苟弛。X 是 A 的傳遞性依賴,但是兩條依賴路徑上有兩個(gè)版本的 X阁将,那么哪個(gè) X 會(huì)被 Maven 解析使用呢膏秫??jī)蓚€(gè)版本都被解析顯然是不對(duì)的,因?yàn)槟菚?huì)造成依賴重復(fù)做盅,因此必須選擇-一個(gè)缤削。Maven 依賴調(diào)解(Dependency Mediation)的第一原則是:路徑最近者優(yōu)先。該例中 X(1.0) 的路徑長(zhǎng)度為 3吹榴,而 X(2.0) 的路徑長(zhǎng)度為 2亭敢,因此 X(2.0) 會(huì)被解析使用。
依賴調(diào)解第一原則不能解決所有問題腊尚,比如這樣的依賴關(guān)系: A->B->Y(1.0)吨拗,A->C->Y(2.0), Y(1.0) 和 Y(2.0) 的依賴路徑長(zhǎng)度是一樣的婿斥,都為 2劝篷。那么到底誰(shuí)會(huì)被解析使用呢?在 Maven 2.0. 8 及之前的版本中民宿,這是不確定的娇妓,但是從 Maven2. 0.9 開始,為了盡可能避免構(gòu)建的不確定性活鹰,Maven 定義了依賴調(diào)解的第二原則:第一聲明者優(yōu)先哈恰。在依賴路徑長(zhǎng)度相等的前提下,在 POM 中依賴聲明的順序決定了誰(shuí)會(huì)被解析使用志群,順序最靠前的那個(gè)依賴優(yōu)勝着绷。該例中,如果 B 的依賴聲明在 C 之前锌云,那么 Y(1.0) 就會(huì)被解析使用荠医。
可以使用 maven-dependency-plugin 的一些目標(biāo)來輔助查看項(xiàng)目的依賴關(guān)系:
-
mvn dependency:list
命令列出已解析出的顯式聲明的依賴項(xiàng),不包括間接依賴項(xiàng)桑涎。 -
mvn dependency:tree
命令來列出實(shí)際生效的依賴項(xiàng)彬向。 -
mvn dependency:analyze
命令來分析此項(xiàng)目的依賴關(guān)系并確定哪些是已顯式聲明且已使用的依賴項(xiàng)、哪些是未顯式聲明但已使用的依賴項(xiàng)攻冷、哪些已顯式聲明但未使用的依賴項(xiàng)娃胆。
依賴版本規(guī)范
依賴項(xiàng)的 version
元素定義了版本需求,用來計(jì)算依賴項(xiàng)的版本等曼。軟需求(Soft Requirement)可以被依賴關(guān)系圖中同一工件的不同版本所替代里烦。硬需求(Hard Requirement)要求特定的一個(gè)或多個(gè)版本凿蒜,并覆蓋軟需求。如果不存在滿足當(dāng)前項(xiàng)目所有硬需求的依賴項(xiàng)版本招驴,則構(gòu)建失敗篙程。
版本需求具有以下語(yǔ)法:
-
1.0
:1.0 的軟需求。如果依賴關(guān)系樹中之前沒有出現(xiàn)其他版本别厘,則使用 1.0虱饿。 -
[1.0]
:1.0 的硬需求。使用 1.0 且僅使用 1.0触趴。 -
(,1.0]
:任何 <=1.0 的版本的硬需求氮发。 -
[1.2,1.3]
:1.2 和 1.3 之間任何版本的硬需求(包含 1.2 和 1.3 版本)。 -
[1.0,2.0)
:1.0 <=x< 2.0冗懦,位于 1.0 版本(含)和 2.0 版本(不含)之間的任何版本的硬需求爽冕。 -
[1.5,)
:任何大于或等于 1.5 的版本的硬需求。 -
(,1.0],[1.2,)
:任何小于或等于 1.0披蕉,大于或等于 1.2颈畸,但不等于 1.1 的版本的硬需求。多個(gè)需求用逗號(hào)分隔没讲。 -
(,1.1),(1.1,)
:除 1.1 以外的任何版本的硬需求眯娱;例如,因?yàn)?1.1 有一個(gè)嚴(yán)重的漏洞爬凑。
Maven 選擇滿足當(dāng)前項(xiàng)目所有硬需求的最高版本的依賴項(xiàng)徙缴。如果沒有能夠滿足所有的硬需求的版本,那么構(gòu)建就會(huì)失敗嘁信。
版本順序規(guī)范
如果版本字符串在語(yǔ)法上是正確的語(yǔ)義化版本 1.0.0 規(guī)范 的版本號(hào)于样,那么在幾乎所有情況下,版本比較都遵循該規(guī)范中概述的優(yōu)先規(guī)則潘靖。這些版本是常見字母數(shù)字的 ASCII 字符串穿剖,如 2.15.2-alpha。更準(zhǔn)確地說卦溢,如果要比較的兩個(gè)版本號(hào)與語(yǔ)義版本控制規(guī)范中 BNF 語(yǔ)法中的 valid semver
產(chǎn)品相匹配糊余,則這是正確的。Maven 不考慮該規(guī)范所暗示的任何語(yǔ)義既绕。
重要提示:這僅適用于語(yǔ)義化版本 1.0.0 規(guī)范啄刹。Maven 版本順序算法與語(yǔ)義化版本 2.0.0 標(biāo)準(zhǔn)不兼容涮坐。特別是凄贩,Maven 對(duì)加號(hào)并不做特殊處理,也不考慮構(gòu)建標(biāo)識(shí)符袱讹。當(dāng)版本字符串不遵循語(yǔ)義化版本控制時(shí)疲扎,需要一組更復(fù)雜的規(guī)則昵时。Maven 使用點(diǎn)號(hào)(.
)和連字符(-
)之間標(biāo)記、數(shù)字與字母的轉(zhuǎn)換處來分割出坐標(biāo)椒丧。點(diǎn)號(hào)(.
)和連字符(-
)作為分隔符將被記錄壹甥,并將對(duì)順序產(chǎn)生影響。數(shù)字和字幕之間的轉(zhuǎn)換相當(dāng)于連字符壶熏、連續(xù)的分隔符之間的空標(biāo)記將替換為 0
句柠。這將提供一系列帶有 .
或 -
前綴的版本號(hào)(數(shù)字標(biāo)記)和版本限定符(非數(shù)字標(biāo)記)。分割和替換示例:1-1.foo-bar1baz-.1
->
1-1.foo-bar-1-baz-0.1
棒假。
然后溯职,從版本末尾開始,對(duì)尾部的 null
值(0
, ""
, "final
", "ga
")將被切除帽哑。該處理在每個(gè)剩余的連字符處從頭到尾不斷重復(fù)谜酒。切除示例:
-
1.0.0
->1
-
1.ga
->1
-
1.final
->1
-
1.0
->1
-
1.
->1
-
1-
->1
-
1.0.0-foo.0.0
->1-foo
-
1.0.0-0.0.0
->1
版本順序是該前綴標(biāo)記序列的字典順序(lexicographical order
),較短的一個(gè)標(biāo)記填充了足夠多的 null
值妻枕,并具有匹配的前綴僻族,與較長(zhǎng)的標(biāo)記具有相同的長(zhǎng)度。填充 null
值取決于另一版本的前綴:0
表示 .
屡谐,而 -
表示 .
述么。帶前綴的標(biāo)記順序?yàn)椋?/p>
-
如果前綴相同,則比較標(biāo)記:
數(shù)字標(biāo)記具有自然順序康嘉。
-
非數(shù)字標(biāo)記(“限定符”)按字母順序排列碉输,但以下標(biāo)記按字母順序排在第一位:"
alpha
" < "beta
" < "milestone
" < "rc
" = "cr
" < "snapshot
" < "" = "final
" = "ga
" < "sp
"- "
alpha
"、"beta
" 和 "milestone
" 限定符在后面直接跟一個(gè)數(shù)字時(shí)亭珍,可以分別縮短為a
敷钾、b
和m
。
- "
或者:"
.qualifier
" < "-qualifier
" < "-number
" < ".number
"肄梨。
最終結(jié)果示例:
- "
1
" < "1.1
"(數(shù)字填充) - "
1-snapshot
" < "1
" < "1-sp
"(限定符填充) - "
1-foo2
" < "1-foo10
"(正確地自動(dòng)“切換”到數(shù)字順序) - "
1.foo
" < "1-foo
" < "1-1
" < "1.1
" - "
1.ga
" = "1-ga
" = "1-0
" = "1.0
" = "1
"(移除末尾的null
值) - "
1-sp
" > "1-ga
" - "
1-sp.1
" > "1-ga.1
" - "
1-sp-1
" < "1-ga-1
" = "1-1
"(移除連字符處的null
值) - "
1-a1
" = "1-alpha-1
"
注意:與某些設(shè)計(jì)文檔中所述相反阻荒,對(duì)于版本順序,snapshot 的處理方式與 release 或任何其他限定符的處理方式?jīng)]有區(qū)別众羡。
版本順序測(cè)試
Maven 發(fā)行版包括一個(gè)比較指定版本之間順序的工具侨赡。有疑問時(shí),請(qǐng)自行運(yùn)行粱侣。您可以這樣運(yùn)行它:
java -jar ${MAVEN_HOME}/lib/maven-artifact-3.3.9.jar [versions...]
示例
$ java -jar ./lib/maven-artifact-3.3.9.jar 1 2 1.1
Display parameters as parsed by Maven (in canonical form) and comparison result:
1. 1 == 1
1 < 2
2. 2 == 2
2 > 1.1
3. 1.1 == 1.1
依賴排除
使用 exclusion
元素可以讓 Maven 在包含某個(gè)依賴項(xiàng)的時(shí)候不包含該依賴項(xiàng)的某些間接依賴項(xiàng)(換句話說羊壹,它的可傳遞依賴項(xiàng))。exclusions
元素可以包含一個(gè)或多個(gè) exclusion
元素齐婴,每個(gè)元素都包含一個(gè) groupId 和一個(gè) artifactId油猫,表示要排除的依賴項(xiàng)。與 optional
(可能安裝和使用柠偶,也可能不安裝情妖、不使用)不同睬关,排除會(huì)主動(dòng)從依賴關(guān)系樹中刪除對(duì)應(yīng)的依賴項(xiàng)。例如毡证,maven-embedder 間接依賴于 maven-core电爹,我們不希望使用它或它的依賴項(xiàng),那么我們顯式地將 maven-core 的 groupId 和 artifact 放在 exclusion
元素中 料睛。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>
如果某個(gè)依賴項(xiàng)的作用域可能有無(wú)丐箩、當(dāng)前版本有安全漏洞、或與項(xiàng)目中的其他依賴項(xiàng)沖突恤煞,就有必要裁掉某個(gè)依賴項(xiàng)的可傳遞依賴項(xiàng)阱州。使用通配符排除可以輕松排除依賴項(xiàng)的所有可傳遞依賴項(xiàng)诈茧。在以下情況下,您可能正在使用 maven-embedder,并且您希望自己管理所使用的依賴項(xiàng)锤躁,因此您可以裁掉所有可傳遞的依賴項(xiàng):
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>
繼承
Maven 為構(gòu)建管理帶來的一個(gè)強(qiáng)大的補(bǔ)充是項(xiàng)目繼承的概念搁料。諸如 Ant 的構(gòu)建系統(tǒng)可以模擬繼承,但 Maven 在項(xiàng)目對(duì)象模型中已經(jīng)顯式地聲明了繼承系羞。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
</project>
對(duì)于父項(xiàng)目來說郭计,其 pom.xml 中的 packaging
元素的值必須為 pom
類型。packaging
元素值會(huì)綁定到一組生命周期階段的目標(biāo)椒振。例如昭伸,如果打包是 jar,那么打包階段將執(zhí)行 jar:jar
目標(biāo)澎迎。父 POM 中的大多數(shù)元素都可以由其子 POM 繼承庐杨,包括:
- groupId
- version
- description
- url
- inceptionYear
- organization
- licenses
- developers
- contributors
- mailingLists
- scm
- issueManagement
- ciManagement
- properties
- dependencyManagement
- dependencies
- repositories
- pluginRepositories
- build
- plugin executions with matching ids
- plugin configuration
- etc.
- reporting
- profiles
未繼承的元素包括:
- artifactId
- name
- prerequisites
子 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<relativePath>../my-parent</relativePath>
</parent>
<artifactId>my-project</artifactId>
</project>
請(qǐng)注意: relativePath
元素不是必需的,但可以作為 Maven 的一個(gè)標(biāo)志夹供,在搜索本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)之前灵份,先搜索 relativePath
元素值所指定的該項(xiàng)目的父項(xiàng)目的路徑。
Super POM
與面向?qū)ο缶幊讨袑?duì)象的繼承類似哮洽,擴(kuò)展父 POM 的 POM 從父 POM 繼承某些值填渠。此外,正如 Java 對(duì)象最終繼承自 java.lang.Object 一樣鸟辅,所有項(xiàng)目對(duì)象模型都繼承自一個(gè)基礎(chǔ)的 Super POM氛什。下面的代碼片段是 Maven 3.5.4 的 Super POM。
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
通過創(chuàng)建一個(gè)最小的 pom.xml
并在命令行上執(zhí)行:mvn help:effective-pom
匪凉,可以了解 Super POM 是如何影響項(xiàng)目對(duì)象模型的屉更。
依賴管理
除了繼承某些頂級(jí)元素外,父 POM 中的 <dependencyManagement>
元素可以幫助管理其所有子 POM 的依賴關(guān)系信息洒缀。父 POM 中 <dependencyManagement>
元素中所聲明的依賴項(xiàng)詳細(xì)信息會(huì)被子 POM 所繼承瑰谜,如果子 POM 在其 <dependecies>
元素中聲明了相同的依賴項(xiàng),則可以省略某些依賴項(xiàng)配置树绩,比如 version
萨脑、scope
。雖然父 POM 的 <dependencyManagement>
元素中設(shè)置了某個(gè)依賴項(xiàng)的詳細(xì)信息饺饭,但如果子 POM 中沒有使用對(duì)應(yīng)的 groupId
和 artifactId
來顯式使用該繼承的依賴項(xiàng)渤早,那么該子 POM 則不會(huì)使用該依賴項(xiàng)。當(dāng)然瘫俊,子 POM 也可以根據(jù)自己的實(shí)際情況來使用不同的依賴項(xiàng)配置來覆蓋所繼承的依賴項(xiàng)配置鹊杖。
比如悴灵,如果 my-parent 項(xiàng)目在其 dependencyManagement
元素中定義對(duì) junit:junit:4.12
的依賴關(guān)系,那么從這個(gè)項(xiàng)目繼承的子 POM 只需要提供 groupId=junit
和 artifactId=junit
就可以使用父 POM 中聲明的這個(gè)依賴項(xiàng)骂蓖,Maven 將自動(dòng)填充父 POM 中所設(shè)置的 JUnit 依賴項(xiàng)版本积瞒。這種方法的好處是顯而易見的〉窍拢可以在一個(gè)中心位置配置依賴項(xiàng)的詳細(xì)信息茫孔,然后這些配置將傳播到所有子 POM。
聚合
通過 <modules>
元素來聲明多個(gè)模塊的項(xiàng)目稱為聚合項(xiàng)目(或多模塊項(xiàng)目)被芳,聚合項(xiàng)目的 <packaging>
元素值也必須為 pom
缰贝。<modules>
元素的子元素<module>
指定某個(gè)子模塊相對(duì)于聚合項(xiàng)目的相對(duì)路徑。一般將聚合項(xiàng)目的子模塊項(xiàng)目放在聚合項(xiàng)目根目錄下作為子目錄存在畔濒,但不是絕對(duì)剩晴。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
<modules>
<!-- 將聚合項(xiàng)目的子模塊項(xiàng)目放在聚合項(xiàng)目根目錄下作為子目錄存在 -->
<module>my-project</module>
<!-- 聚合項(xiàng)目的子模塊項(xiàng)目目錄與聚合項(xiàng)目目錄同級(jí) -->
<module>../another-project</module>
</modules>
</project>
在列出模塊時(shí),即使各子模塊之間有依賴關(guān)系侵状,也不需要考慮子模塊聲明順序李破。Maven 會(huì)對(duì)模塊進(jìn)行拓?fù)渑判颍@樣被依賴模塊總是在依賴模塊之前構(gòu)建壹将。但各模塊之間不能出現(xiàn)循環(huán)依賴嗤攻,否則,Maven 就會(huì)失敗诽俯。
繼承 VS 聚合
繼承和聚合通過單個(gè)高級(jí) POM 創(chuàng)建一個(gè)很好的動(dòng)態(tài)來控制構(gòu)建妇菱。父項(xiàng)目和聚合項(xiàng)目的 <packaging>
元素值都是 pom
,兩者除了 POM 以外均不含其他內(nèi)容暴区。經(jīng)常會(huì)看到一個(gè)項(xiàng)目既是父項(xiàng)目又是聚合項(xiàng)目闯团,但繼承和聚合不是一個(gè)概念。兩者不同之處如下:
- 父項(xiàng)目的主要目的是為了消除重復(fù)配置仙粱。父項(xiàng)目的 pom.xml 中可以不含模塊而單單作為一個(gè)父項(xiàng)目來被其子項(xiàng)目通過
<parent>
元素來繼承竣蹦,此時(shí)产徊,父項(xiàng)目?jī)H僅是父項(xiàng)目,而不是一個(gè)聚合項(xiàng)目。父項(xiàng)目不知道哪些子項(xiàng)目繼承了它嚣潜,而子項(xiàng)目知道它繼承了哪個(gè)父項(xiàng)目更舞。 - 聚合項(xiàng)目的目的是便于管理多個(gè)模塊掠剑。聚合項(xiàng)目的 pom.xml 中可通過包含若干個(gè)子模塊竟痰,從而將這些子模塊歸為一個(gè)組來統(tǒng)一管理這些子模塊,比如硬霍,統(tǒng)一 clean帜慢、compile 所有子模塊。而子模塊不需要特殊的聲明。聚合項(xiàng)目知道自己聚合了哪些模塊粱玲,但子模塊不知道誰(shuí)聚合了自己以及和誰(shuí)一起被聚合躬柬。
property
Maven 的 property 是值占位符,就像 Ant 中的 property 一樣抽减。它們的值可以通過使用符號(hào) ${X}
在 POM 中的任何位置訪問允青,其中 X
是 property】杷Γ或者它們可以被插件用作默認(rèn)值,例如:
<project>
...
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- Following project.-properties are reserved for Maven in will become elements in a future POM definition. -->
<!-- Don't start your own properties properties with project. -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
...
</project>
Property 有五種不同的風(fēng)格:
-
env.X
:在變量前面加上env.
將返回 shell 的環(huán)境變量堪嫂。例如偎箫,${env.PATH}
包含 PATH 環(huán)境變量。雖然環(huán)境變量本身在 Windows 上不區(qū)分大小寫皆串,但 property 的查找是區(qū)分大小寫的淹办。換句話說,雖然 Windows shell 為%PATH%
和%Path%
返回相同的值恶复,但 Maven 區(qū)分了${env.PATH}
和${env.Path}
怜森。為了可靠性起見,環(huán)境變量的名稱被規(guī)范化為所有大寫谤牡。 -
project.x
:POM 中以點(diǎn)號(hào)(.
)表示的路徑將包含相應(yīng)元素的值副硅。例如:<project><version>1.0</version></project>
可以通過${project.version}
來訪問。 -
settings.x
:settings.xml
中以點(diǎn)號(hào)(.
)表示的路徑將包含相應(yīng)元素的值翅萤。例如:<settings><offline>false</offline></settings>
可通過${settings.offline}
訪問恐疲。 - Java 系統(tǒng)屬性:通過
java.lang.System.getProperties()
訪問的所有屬性都可以作為 POM property 使用,例如${java.home}
套么。 -
x
:在 POM 中的<properties/>
元素內(nèi)設(shè)置培己。<properties><someVar>value</someVar></properties>
的值可以用作${someVar}
。
Build Setting
構(gòu)建
根據(jù) POM 4.0.0 XSD胚泌,<build>
元素在概念上分為兩部分省咨,對(duì)應(yīng)一個(gè) BaseBuild
類型,它包含兩個(gè) <build>
元素共有的元素集:<project>
元素下和 <profiles>
元素下的頂級(jí) <build>
元素玷室;還有一個(gè) Build
類型零蓉,它包含 BaseBuild
集合以及頂層定義的更多元素。讓我們從分析兩者之間的共同點(diǎn)開始穷缤。注意:這些不同的 <build>
元素可以表示為 project build
和 profile build
壁公。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<!-- "Project Build" contains more elements than just the BaseBuild set -->
<build>...</build>
<profiles>
<profile>
<!-- "Profile Build" contains a subset of "Project Build"s elements -->
<build>...</build>
</profile>
</profiles>
</project>
基礎(chǔ)構(gòu)建元素
BaseBuild
類型就像聽起來的那樣,POM 中兩個(gè) <build>
元素中的定級(jí)子元素元素的集合绅项。
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
...
</build>
-
defaultGoal
:當(dāng)沒有給定目標(biāo)或階段時(shí)所要執(zhí)行的默認(rèn)目標(biāo)或階段紊册。如果給定了一個(gè)目標(biāo),那么應(yīng)該在命令行中定義它(例如jar:jar
)。如果定義了一個(gè)階段(如install
)囊陡,則情況也是如此芳绩。 -
directory
:構(gòu)建輸出的目標(biāo)目錄。它默認(rèn)為${basedir}/target
撞反。 -
finalName
:這是最終構(gòu)建項(xiàng)目時(shí)的項(xiàng)目名稱(無(wú)文件擴(kuò)展名妥色,例如:my-project-1.0.jar)。它默認(rèn)為${artifactId}-${version}
遏片。然而嘹害,finalName
的術(shù)語(yǔ)有點(diǎn)用詞不當(dāng),因?yàn)闃?gòu)建項(xiàng)目的插件完全有權(quán)忽略/修改這個(gè)名稱(但通常不會(huì))吮便。例如笔呀,如果maven-jar-plugin
插件被配置為給 jar 一個(gè)test
的classifier
,那么上面定義的實(shí)際 jar 將被構(gòu)建為 my-project-1.0-test.jar髓需。 -
filter
:指定一個(gè)*.properties
文件许师,該文件中定義的name=value
對(duì)在構(gòu)建時(shí)將用于替換資源中的${name}
字符串。上面的示例在filters/
目錄下定義了 filter1.properties 文件僚匆。Maven 的默認(rèn)過濾器目錄是${basedir}/src/main/filters/
微渠。
資源
<build>
元素的另一個(gè)特性是指定資源在項(xiàng)目中的位置。資源通常不是代碼咧擂,它們不會(huì)編譯逞盆,而是要捆綁在項(xiàng)目中或用于各種其他用途(如代碼生成、用作項(xiàng)目的配置文件)松申。例如纳击,Plexus 項(xiàng)目需要在 META-INF/plexus
目錄中存放一個(gè) configuration.xml
文件(指定容器的組件配置)。盡管我們可以同樣輕松地將此文件放在 src/main/resources/META-INF/plexus
中攻臀,但我們希望將它自己的目錄 src/main/plexus
提供給 Plexus焕数。為了讓 JAR 插件正確綁定資源,您可以指定類似以下內(nèi)容的資源:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<resources>
<!-- 指定模塊中所用資源所在的目錄 -->
<resource>
<!-- 默認(rèn)資源目錄為src/main/resources -->
<directory>src/main/resources</directory>
<!-- filtering設(shè)置為true會(huì)將文本類型的資源文件中使用${name}表示的屬性值替換為對(duì)應(yīng)屬性值(這些屬性可以有五種聲明方式刨啸,
參考關(guān)于Property的說明 -->
<filtering>true</filtering>
<!-- 指定需要輸出的資源文件(文本文件可以使用屬性引用的替換) -->
<!-- 不輸出src/main/resources目錄下的所有.properties和.xml資源文件 -->
<includes>
<include>**/*.properties</include> <!-- 輸出src/main/resources目錄下的所有txt資源文件 -->
<include>**/*.xml</include> <!-- 輸出src/main/resources目錄下的所有xml資源文件 -->
</includes>
<!-- 指定不需要輸出資源文件(二進(jìn)制文件不能使用屬性引用的替換堡赔,否則可能會(huì)損壞二進(jìn)制文件) -->
<!-- 不輸出src/main/resources目錄下的所有.bmp和.jpg資源文件 -->
<excludes>
<exclude>**/*.bmp</exclude>
<exclude>**/*.jpg</exclude>
</excludes>
</resource>
<!-- 可以使用多個(gè)resource元素來指定多個(gè)資源目錄 -->
<resource>
<directory>src/main/resources-filtered</directory>
<!-- includes和excludes可以組合使用。如下配置會(huì)輸出資源目錄下的所有txt文件但除了名稱中包含test的txt文件以外 -->
<includes>
<include>**/*.txt</include>
</includes>
<excludes>
<exclude>**/*test*.*</exclude>
</excludes>
</resource>
</resources>
<testResources>
<testResource>
<!-- ... -->
</testResource>
</testResources>
...
</build>
</project>
-
<resources>
:是<resource>
元素的列表设联,每個(gè)<resource>
元素用于選擇將哪些資源文件復(fù)制到構(gòu)建輸出的類路徑下善已,執(zhí)行復(fù)制操作之前還可能對(duì)文本類資源文件中的 property 引用進(jìn)行替換。 -
<targetPath>
:資源經(jīng)構(gòu)建之后的存放目錄离例。目標(biāo)路徑默認(rèn)為基本目錄换团。一般會(huì)把META-INF
目標(biāo)目錄會(huì)打包到 JAR 包中。 -
<filtering>
:為true
或false
宫蛆,表示是否要替換資源文件中的某些 property 引用艘包。請(qǐng)注意,如果要替換 property 的引用,不一定非要在<filters>
定義*.properties
文件想虎,資源還可以使用 POM 中默認(rèn)定義的 property (例如${project.version}
)卦尊、 傳遞到命令行的-D
選項(xiàng)參數(shù)(例如,-Dname=value
)或由<properties>
元素顯式定義的 property舌厨。 -
<directory>
:這個(gè)元素的值定義了在哪里可以找到資源岂却,默認(rèn)為${basedir}/src/main/resources
。 -
<includes>
:一組文件模式裙椭,使用*
作為通配符躏哩,指定<directory>
元素值所指定目錄下的哪些文件和目錄要包含在<targetPath>
目錄下。 -
<excludes>
:與<includes>
元素結(jié)構(gòu)相同揉燃,但指定要排除的文件扫尺。如果一個(gè)路徑同時(shí)匹配<includes>
和<excludes>
中的模式,則忽略匹配的包含模式而排除處理你雌。 -
<testResources>
:<testResources>
元素包含<testResource>
元素器联。它們的定義類似于資源元素二汛,但在測(cè)試階段自然使用婿崭。一個(gè)區(qū)別是項(xiàng)目的默認(rèn)(超級(jí) POM 定義的)測(cè)試資源目錄是${basedir}/src/test/resources
。未部署測(cè)試資源肴颊。
再看下面一個(gè) Spring Boot 項(xiàng)目管理不同運(yùn)行環(huán)境下資源文件的例子:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<!-- 聲明了三個(gè)運(yùn)行環(huán)境的 profile:開發(fā)氓栈、測(cè)試、UAT婿着、生產(chǎn)授瘦。當(dāng)通過id激活了某個(gè) profile 之后,對(duì)應(yīng)的activeProfile屬性就會(huì)起作用 -->
<profiles>
<profile>
<id>dev</id>
<properties>
<activeProfile>dev-res</activeProfile>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<activeProfile>test-res</activeProfile>
</properties>
</profile>
<profile>
<id>uat</id>
<properties>
<activeProfile>uat-res</activeProfile>
</properties>
</profile>
<profile>
<id>pro</id>
<properties>
<activeProfile>pro-res</activeProfile>
</properties>
</profile>
</profiles>
...
<resources>
<resource>
<!-- 默認(rèn)資源目錄為src/main/resources竟宋。建議將不同環(huán)境下同名的資源文件分開存放 -->
<!-- 假如src/main/resources存在以下子路徑:env/dev-res/提完、env/test-res/、env/uat-res/丘侠、env/pro-res/徒欣,
每個(gè)子路徑下存放了一些對(duì)應(yīng)運(yùn)行環(huán)境的資源文件 -->
<directory>src/main/resources</directory>
<!-- 排除env子目錄下的所有資源文件 -->
<excludes>
<exclude>env/**</exclude>
</excludes>
</resource>
<!-- 使用另一個(gè)resource元素來包含某個(gè)激活的 profile 中 activeProfile 屬性值所構(gòu)成的資源路徑 -->
<!-- src/main/resources/env/${activeProfile} 路徑下的資源文件將直接復(fù)制到構(gòu)建輸出目錄的類路徑下 -->
<resource>
<directory>src/main/resources/env/${activeProfile}</directory>
<includes>
<include>**</include>
</includes>
</resource>
</resources>
...
</build>
</project>
在上面的例子中,通過激活某個(gè) profile 可以選擇將 src/main/resources/env/${activeProfile}
路徑下的資源文件復(fù)制到構(gòu)建輸出的類路徑下蜗字,就不用來回復(fù)制替換不同運(yùn)行環(huán)境下的資源文件了打肝。如果你使用 Intellig IDEA 進(jìn)行開發(fā),可以直接在 Maven 插件提供的 Profile 復(fù)選框勾選來激活對(duì)應(yīng)的 profile挪捕,非常方便粗梭。也可以通過命令行參數(shù)來激活某個(gè) profile。
插件
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
</plugins>
</build>
</project>
除了 groupId:artifactId:version
的標(biāo)準(zhǔn)坐標(biāo)之外级零,還有一些用于配置插件或與構(gòu)建進(jìn)行交互的元素断医。
extensions
:true
或false
,是否加載此插件的擴(kuò)展。它默認(rèn)為false
孩锡。inherited
:true
或false
酷宵,該插件配置是否應(yīng)用于從該 POM 繼承的子 POM。默認(rèn)值為true
躬窜。-
configuration
:這是特定于單個(gè)插件的浇垦。在不深入討論插件如何工作的機(jī)制的情況下,只需說明插件 Mojo 可能期望的任何屬性(javamojobean中的getter和setter)都可以在這里指定荣挨。在上面的示例中男韧,我們將在maven-jar-plugin
的 Mojo 中設(shè)置classifier
為test
。值得注意的是默垄,所有配置元素此虑,無(wú)論它們位于 POM 中的何處,都旨在將值傳遞給另一個(gè)底層系統(tǒng)口锭,例如插件朦前。換句話說:POM 語(yǔ)法從未顯式聲明需要configuration
元素中的值,但插件目標(biāo)完全有權(quán)要求必需提供configuration
元素中的值鹃操。如果您的 POM 繼承自一個(gè)父 POM韭寸,它將從父級(jí)的
<build>/<plugins>
元素和<pluginManagement>
元素中繼承插件配置。默認(rèn)配置繼承
為了說明荆隘,請(qǐng)看來自某個(gè)父 POM 的以下片段:
<plugin> <groupId>my.group</groupId> <artifactId>my-plugin</artifactId> <configuration> <items> <item>parent-1</item> <item>parent-2</item> </items> <properties> <parentKey>parent</parentKey> </properties> </configuration> </plugin>
下面的 POM 片段所在的項(xiàng)目繼承了上面 POM 片段所在的項(xiàng)目:
<plugin> <groupId>my.group</groupId> <artifactId>my-plugin</artifactId> <configuration> <items> <item>child-1</item> </items> <properties> <childKey>child</childKey> </properties> </configuration> </plugin>
默認(rèn)行為是根據(jù)元素名稱合并配置元素的內(nèi)容恩伺。如果子 POM 具有父 POM 所沒有的元素,或子 POM 具有和父 POM 相同的元素椰拒,則子 POM 中的該元素將成為有效值晶渠。如果父 POM 具有子 POM 所有沒有的元素,則父 POM 中的該元素將成為有效值燃观。這純粹是對(duì) XML 的操作褒脯,不涉及插件本身的代碼或配置。只涉及元素缆毁,而不涉及它們的值番川。
將這些規(guī)則應(yīng)用到示例中,子 POM 中實(shí)際生效的結(jié)果如下:
<plugin> <groupId>my.group</groupId> <artifactId>my-plugin</artifactId> <configuration> <items> <item>child-1</item> </items> <properties> <childKey>child</childKey> <parentKey>parent</parentKey> </properties> </configuration> </plugin>
高級(jí)配置集成
通過向
<configuration>
元素的子元素添加屬性积锅,可以控制子 POM 如何從父 POM 繼承配置爽彤。屬性為combine.children
和combine.self
。在子 POM 中使用這些屬性來控制 Maven 如何將父級(jí)的插件配置與子級(jí)的顯式配置相結(jié)合缚陷。以下是子配置中的兩個(gè)屬性的示例:
<configuration> <items combine.children="append"> <!-- combine.children="merge" is the default --> <item>child-1</item> </items> <properties combine.self="override"> <!-- combine.self="merge" is the default --> <childKey>child</childKey> </properties> </configuration>
那么适篙,有效配置如下:
<configuration> <items combine.children="append"> <item>parent-1</item> <item>parent-2</item> <item>child-1</item> </items> <properties combine.self="override"> <childKey>child</childKey> </properties> </configuration>
combine.children=“append”
將按順序連接父元素和子元素中的值。另一方面箫爷,combine.self=“override”
完全覆蓋對(duì)應(yīng)的父配置嚷节。如果嘗試對(duì)一個(gè)元素同時(shí)使用combine.self=“override”
和combine.children=“append”
聂儒,則override
將占據(jù)上風(fēng)。請(qǐng)注意硫痰,這些 attribute 僅應(yīng)用于聲明它們的配置元素衩婚,而不會(huì)傳播到下一級(jí)的嵌套子元素。也就是說效斑,如果來自子 POM 的
<item>
元素的內(nèi)容是一個(gè)復(fù)雜的結(jié)構(gòu)而不是文本非春,那么它的子元素仍將遵循默認(rèn)的合并策略,除非這些子元素使用了combine.*
attribute缓屠。combine.*
attribute 從父 POM 繼承到子 POM奇昙。將這些 attribute 添加到父 POM 時(shí)要小心,因?yàn)檫@可能會(huì)影響其子 POM 或其孫子 POM敌完。 dependencies
:在 POM 中的許多位置都可以看到<dependencies>
元素储耐,當(dāng)該元素可以出現(xiàn)在<plugin>
元素中時(shí), 其的結(jié)構(gòu)和功能與在基礎(chǔ)構(gòu)建下時(shí)相同滨溉。不同的是什湘,<plugin>
元素下的<dependencies>
元素不再作為項(xiàng)目的依賴項(xiàng),而是作為它們所處插件的依賴項(xiàng)晦攒。它的功能是改變插件的依賴項(xiàng)列表闽撤,可能是通過排除刪除未使用的運(yùn)行時(shí)依賴項(xiàng),或者改變所需依賴項(xiàng)的版本勤家。-
executions
:一個(gè)插件可能有多個(gè)目標(biāo)腹尖。每個(gè)目標(biāo)可能有一個(gè)單獨(dú)的配置柳恐,甚至可能將插件的目標(biāo)綁定到一個(gè)不同的階段伐脖。<executions>
配置一個(gè)插件目標(biāo)的<execution>
。例如乐设,假設(shè)您想要將antrun:run
目標(biāo)綁定到verify
階段讼庇。我們希望任務(wù)回顯構(gòu)建目錄,并通過將inherited
設(shè)置為false
避免將此配置傳遞給其子級(jí)(假設(shè)它是父級(jí))近尚。您將得到如下<execution>
:<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> ... <build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>echodir</id> <goals> <goal>run</goal> </goals> <phase>verify</phase> <inherited>false</inherited> <configuration> <tasks> <echo>Build Dir: ${project.build.directory}</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
-
id
:不言自明蠕啄,用于在所有執(zhí)行塊中標(biāo)識(shí)該執(zhí)行塊。當(dāng)階段運(yùn)行時(shí)戈锻,它將以以下形式顯示:[plugin:goal execution: id]
歼跟。在本例中:[antrun:run execution: echodir]
。 -
goals
:與所有復(fù)數(shù)名稱的 POM 元素一樣格遭,它是一個(gè)<goal>
元素的列表哈街。 -
phase
:這是<goals>
列表執(zhí)行時(shí)所處的階段。這是一個(gè)非常強(qiáng)大的選項(xiàng)拒迅,允許將任何目標(biāo)綁定到構(gòu)建生命周期的任何階段骚秦,從而改變 Maven 的默認(rèn)行為她倘。 -
inherited
:與上面的<inherited>
元素一樣,將此設(shè)置為false
將禁止 Maven 將此執(zhí)行傳遞給其子級(jí)作箍。此元素僅對(duì)父 POM 有意義硬梁。 -
configuration
:與上面相同,但是將配置限制在這個(gè)特定的目標(biāo)列表中胞得,而不是插件下的所有目標(biāo)荧止。
-
插件管理
<pluginManagement>
是一個(gè)與 <plugins>
同級(jí)的元素,用于管理插件阶剑。<pluginManagement>
元素包含插件元素的方式與 <plugins>
元素基本相同罩息,不同之處在于,這里的定義僅僅是為子項(xiàng)目或當(dāng)前項(xiàng)目的 <plugins>
元素中實(shí)際引用的插件提供一些默認(rèn)配置个扰,如果子項(xiàng)目或當(dāng)前項(xiàng)目的 <plugins>
元素中沒有使用 <pluginManagement>
元素中的某些插件聲明瓷炮,則子項(xiàng)目或當(dāng)前項(xiàng)目就不會(huì)使用對(duì)應(yīng)插件。子項(xiàng)目完全可以覆蓋所繼承的插件管理的定義递宅。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>pre-process-classes</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>pre-process</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
...
</build>
</project>
如果某個(gè)子 POM 通過以下片段繼承了上面的 POM娘香,或者當(dāng)前 POM 在包含上面 <pluginManagement>
元素聲明的同時(shí),還聲明了在當(dāng)前 POM 中聲明了以下片段的配置办龄,則就可以完全按照 <pluginManagement>
元素所聲明的那樣來使用對(duì)應(yīng)的插件烘绽,而不需要完全照抄一份,因?yàn)橐呀?jīng)從 <pluginManagement>
元素繼承了一些默認(rèn)插件配置俐填。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
</plugins>
...
</build>
</project>
<build>
中的其他元素
XSD 中的 Build
類型表示那些僅可用于項(xiàng)目構(gòu)建的元素安接。盡管有很多額外的元素,但 <project>/<build>
中實(shí)際上只包含兩組 <profile>/<build>
中所缺少的元素:目錄和擴(kuò)展英融。
目錄
目錄元素集位于父 <build>
元素中盏檐,父 <build>
元素將 POM 作為一個(gè)整體設(shè)置各種目錄結(jié)構(gòu)。因?yàn)樗鼈儾淮嬖谟?<profile>/<build>
中驶悟,所以 <profile>
不能修改它們胡野。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
...
</build>
</project>
如果上面的 <*Directory>
元素的值設(shè)置為絕對(duì)路徑(當(dāng)其 property 替換成實(shí)際值時(shí)),則使用該絕對(duì)路徑痕鳍。否則硫豆,則使用相對(duì)于 ${basedir}
目錄的相對(duì)路徑。請(qǐng)注意笼呆,scriptSourceDirectory
在 Maven 中沒有使用熊响,已經(jīng)過時(shí)。
擴(kuò)展
擴(kuò)展(通過 <extensions>
元素)是要在此構(gòu)建中使用的工件的列表诗赌,這些工件將包含在正在運(yùn)行的構(gòu)建的類路徑中汗茄,這些工件可以支持對(duì)構(gòu)建過程的擴(kuò)展,以及激活插件從而更改構(gòu)建生命周期境肾。簡(jiǎn)而言之剔难,擴(kuò)展是在構(gòu)建期間激活的工件胆屿。擴(kuò)展不必實(shí)際執(zhí)行任何操作,也不必包含 Mojo偶宫。因此非迹,擴(kuò)展非常適合指定公共插件接口的多個(gè)實(shí)現(xiàn)中的一個(gè)。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-alpha-3</version>
</extension>
</extensions>
...
</build>
</project>
reporting
<reporting>
元素包含與站點(diǎn)生成階段相關(guān)的元素纯趋。某些 Maven 插件可以生成在 <reporting>
元素下定義和配置的報(bào)告憎兽,例如:生成 Javadoc 報(bào)告。與 <build>
元素配置插件的功能非常相似吵冒,<reporting>
元素具有相同的功能纯命。明顯的區(qū)別在于, <reporting>
元素在 <reportSet>
元素中配置目標(biāo)痹栖,而不是在 <executions>
元素中對(duì)插件目標(biāo)進(jìn)行細(xì)粒度控制祈远。更微妙的區(qū)別是然眼, <reporting>
元素下插件的 <configuration>
可以用作 <build>
中插件的 <configuration>
躺涝,盡管相反的情況并非如此: <build>
中插件 <configuration>
不會(huì)影響 <reporting>
中的插件仔夺。
了解 <build>
元素的人對(duì)于 <reporting>
元素可能唯一不熟悉的是 Boolean 類型的 <excludeDefaults>
元素。此元素指示站點(diǎn)生成器排除默認(rèn)情況下通常生成的報(bào)告南捂。通過 site
構(gòu)建周期生成站點(diǎn)時(shí)吴裤,左側(cè)菜單中會(huì)顯示一個(gè) Project Info
部分,其中包含大量報(bào)告溺健,例如 Project Team
報(bào)告或 Dependencies
列表報(bào)告麦牺。這些報(bào)告目標(biāo)由 maven-project-info-reports-plugin
插件生成的。與其他插件一樣鞭缭,它也可能以下更詳細(xì)的方式被抑制剖膳,從而有效地關(guān)閉項(xiàng)目信息報(bào)告。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<reporting>
<outputDirectory>${basedir}/target/site</outputDirectory>
<plugins>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.0.1</version>
<reportSets>
<reportSet></reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
...
</project>
另一個(gè)區(qū)別是 <plugin>
下的 <outputDirectory>
元素缚去。在 <reporting>
下潮秘,輸出目錄默認(rèn)為 ${basedir}/target/site
琼开。
重要的是要記住易结,一個(gè)插件可能有多個(gè)目標(biāo)。每個(gè)目標(biāo)可能有一個(gè)單獨(dú)的配置柜候。<reportSets>
配置報(bào)告類插件的目標(biāo)的執(zhí)行搞动,這聽起來熟悉吧?關(guān)于構(gòu)建的 <execution>
元素也說了同樣的話渣刷,但有一個(gè)區(qū)別:不能將報(bào)告類插件的目標(biāo)綁定到另一個(gè)階段鹦肿。
例如,假設(shè)我們想要配置要鏈接到 http://java.sun.com/j2se/1.5.0/docs/api/ 的 javadoc:javadoc
目標(biāo)辅柴,但只有 javadoc 目標(biāo)(而不是 maven-javadoc-plugin:jar
)箩溃。我們還希望將此配置傳遞給其子級(jí)瞭吃,并將 <inherited>
設(shè)置為 true。 <reportSets>
類似于以下內(nèi)容:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<reporting>
<plugins>
<plugin>
...
<reportSets>
<reportSet>
<id>sunlink</id>
<reports>
<report>javadoc</report>
</reports>
<inherited>true</inherited>
<configuration>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
</links>
</configuration>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
...
</project>
在 <build>
的 <executions>
和 <reporting>
的 <reportSets>
之間涣旨,現(xiàn)在應(yīng)該清楚它們存在的原因歪架。POM 不僅必須有一種方法來配置插件,還必須配置這些插件的目標(biāo)霹陡。這就是這些元素的用武之地和蚪,使 POM 以最細(xì)的粒度來控制其構(gòu)建行為。
更多項(xiàng)目信息
有幾個(gè)元素不影響構(gòu)建烹棉,而是記錄項(xiàng)目以方便開發(fā)人員攒霹。在生成項(xiàng)目網(wǎng)站時(shí),這些元素中的許多元素用于填充項(xiàng)目詳細(xì)信息浆洗。然而催束,像所有POM聲明一樣,插件可以將它們用于任何事情伏社。以下是最簡(jiǎn)單的元素:
-
name
:除了artifactId
之外泣崩,項(xiàng)目往往有非正式的名字。Sun 的工程師們并沒有將他們的項(xiàng)目稱為java-1.5
洛口,而只是稱之為Tiger
矫付。這里是設(shè)置該值的位置。 -
description
:項(xiàng)目的簡(jiǎn)短易讀描述第焰。盡管這不應(yīng)取代正式的文檔买优,但對(duì) POM 的任何讀者的快速評(píng)論總是有幫助的。 -
url
:項(xiàng)目的主頁(yè)挺举。 -
inceptionYear
:項(xiàng)目最初創(chuàng)建的年份杀赢。
licenses
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<licenses>
是定義如何以及何時(shí)使用項(xiàng)目(或項(xiàng)目的一部分)的法律文件。項(xiàng)目應(yīng)該列出直接應(yīng)用于此項(xiàng)目的許可證湘纵,而不是列出應(yīng)用于項(xiàng)目依賴項(xiàng)的許可證脂崔。
-
name
、url
和comments
:是不言自明的梧喷,以前在其他上下文中也遇到過砌左。建議使用 SPDX 標(biāo)識(shí)符作為許可證名稱。第四個(gè)許可要素是: -
distribution
:描述如何合法發(fā)布項(xiàng)目铺敌。這兩種方法:repo
(可以從 Maven 存儲(chǔ)庫(kù)下載)或manual
(必須手動(dòng)安裝)汇歹。
organization
大多數(shù)項(xiàng)目由某種組織(企業(yè)、私人團(tuán)體等)運(yùn)行偿凭。這里是設(shè)置最基本信息的地方产弹。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<organization>
<name>Codehaus Mojo</name>
<url>http://mojo.codehaus.org</url>
</organization>
</project>
developers
所有項(xiàng)目都由一個(gè)人在某個(gè)時(shí)間創(chuàng)建的文件組成。與圍繞項(xiàng)目的其他系統(tǒng)一樣弯囊,參與項(xiàng)目的人員也與項(xiàng)目有利害關(guān)系痰哨。開發(fā)人員可能是項(xiàng)目核心開發(fā)的成員胶果。請(qǐng)注意,盡管一個(gè)組織可能有許多開發(fā)人員(程序員)作為成員斤斧,但將他們?nèi)苛袨殚_發(fā)人員并不是一種好的形式稽物,而只列出那些直接負(fù)責(zé)代碼的人。一個(gè)很好的經(jīng)驗(yàn)法則是折欠,如果不應(yīng)該因?yàn)轫?xiàng)目聯(lián)系此人贝或,他們就不需要在這里列出。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<developers>
<developer>
<id>jdoe</id>
<name>John Doe</name>
<email>jdoe@example.com</email>
<url>http://www.example.com/jdoe</url>
<organization>ACME</organization>
<organizationUrl>http://www.example.com</organizationUrl>
<roles>
<role>architect</role>
<role>developer</role>
</roles>
<timezone>America/New_York</timezone>
<properties>
<picUrl>http://www.example.com/jdoe/pic</picUrl>
</properties>
</developer>
</developers>
...
</project>
-
id
锐秦、name
咪奖、email
:這些對(duì)應(yīng)于開發(fā)人員的 id(可能是整個(gè)組織中的某個(gè)唯一 id)、開發(fā)人員的姓名和電子郵件地址酱床。 -
organization
羊赵、organizationUrl
:正如您可能猜到的,這是開發(fā)人員的組織名稱和 URL扇谣。 -
roles
:角色應(yīng)指定該人員負(fù)責(zé)的標(biāo)準(zhǔn)操作昧捷。就像一個(gè)人可以戴很多帽子一樣,一個(gè)人可以扮演多個(gè)角色罐寨。 -
timezone
:一個(gè)有效的時(shí)區(qū) ID靡挥,如America/New_York
或Europe/Berlin
,或以小時(shí)(和分?jǐn)?shù))為單位的數(shù)字偏移量(基于開發(fā)人員居住的 UTC 時(shí)間)例如-5
或+1
鸯绿。時(shí)區(qū) ID 是首選跋破,因?yàn)樗鼈儾皇?DST 和時(shí)區(qū)偏移的影響。有關(guān)官方時(shí)區(qū)數(shù)據(jù)庫(kù)和維基百科中的列表瓶蝴,請(qǐng)參考 IANA毒返。 -
properties
:這個(gè)元素是關(guān)于這個(gè)人的任何其他屬性所在的位置。例如舷手,指向個(gè)人圖像或即時(shí)通訊方式的鏈接拧簸。不同的插件可能會(huì)使用這些屬性,也可能只是針對(duì)閱讀 POM 的其他開發(fā)人員男窟。
contributors
<contributors>
就像開發(fā)人員一樣盆赤,在項(xiàng)目的生命周期中扮演著輔助角色。也許貢獻(xiàn)者發(fā)送了一個(gè) bug 修復(fù)蝎宇,或者添加了一些重要的文檔弟劲。一個(gè)健康的開源項(xiàng)目可能會(huì)有比開發(fā)者更多的貢獻(xiàn)者。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<contributors>
<contributor>
<name>Noelle</name>
<email>some.name@gmail.com</email>
<url>http://noellemarie.com</url>
<organization>Noelle Marie</organization>
<organizationUrl>http://noellemarie.com</organizationUrl>
<roles>
<role>tester</role>
</roles>
<timezone>America/Vancouver</timezone>
<properties>
<gtalk>some.name@gmail.com</gtalk>
</properties>
</contributor>
</contributors>
...
</project>
<contributors>
包含的元素集與沒有 id 元素的開發(fā)人員包含的元素集相同姥芥。
環(huán)境設(shè)置
issueManagement
<issueManagement>
定義了所使用的缺陷跟蹤系統(tǒng)(Bugzilla、TestTrack汇鞭、ClearQuest 等)凉唐。雖然沒有什么可以阻止插件將這些信息用于某些事情庸追,但它主要用于生成項(xiàng)目文檔。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<issueManagement>
<system>Bugzilla</system>
<url>http://127.0.0.1/bugzilla/</url>
</issueManagement>
...
</project>
持續(xù)集成管理
在過去幾年中台囱,基于觸發(fā)器或計(jì)時(shí)器(例如淡溯,每小時(shí)或每天)的持續(xù)集成構(gòu)建系統(tǒng)越來越受到手動(dòng)構(gòu)建者的青睞。隨著構(gòu)建系統(tǒng)變得更加標(biāo)準(zhǔn)化簿训,運(yùn)行觸發(fā)器的系統(tǒng)也會(huì)觸發(fā)這些構(gòu)建咱娶。盡管大多數(shù)配置取決于所使用的特定程序(Continuum、Cruise Control,制等)强品,但也有一些配置可能發(fā)生在 POM 內(nèi)膘侮。Maven 在 <notifier>
元素中捕獲了一些重復(fù)設(shè)置。<notifier>
是通知人們某些構(gòu)建狀態(tài)的方式的榛。在以下示例中琼了,此 POM 正在設(shè)置郵件類型的通知程序,并將電子郵件地址配置為用于指定的觸發(fā)器 sendOnError
夫晌、sendOnFailure
雕薪,而不是 sendOnSuccess
或 sendOnWarning
。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<ciManagement>
<system>continuum</system>
<url>http://127.0.0.1:8080/continuum</url>
<notifiers>
<notifier>
<type>mail</type>
<sendOnError>true</sendOnError>
<sendOnFailure>true</sendOnFailure>
<sendOnSuccess>false</sendOnSuccess>
<sendOnWarning>false</sendOnWarning>
<configuration><address>continuum@127.0.0.1</address></configuration>
</notifier>
</notifiers>
</ciManagement>
...
</project>
郵件列表
郵件列表是與人們就項(xiàng)目保持聯(lián)系的一個(gè)很好的工具晓淀。大多數(shù)郵件列表是為開發(fā)人員和用戶提供的所袁。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<mailingLists>
<mailingList>
<name>User List</name>
<subscribe>user-subscribe@127.0.0.1</subscribe>
<unsubscribe>user-unsubscribe@127.0.0.1</unsubscribe>
<post>user@127.0.0.1</post>
<archive>http://127.0.0.1/user/</archive>
<otherArchives>
<otherArchive>http://base.google.com/base/1/127.0.0.1</otherArchive>
</otherArchives>
</mailingList>
</mailingLists>
...
</project>
-
subscribe
、unsubscribe
:這些元素指定用于執(zhí)行相關(guān)操作以訂閱上面的用戶列表的電子郵件地址凶掰。要訂閱上面的用戶列表纲熏,用戶將向user-subscribe@127.0.0.1
發(fā)送電子郵件。 -
archive
:此元素指定舊郵件列表電子郵件存檔的 url(如果存在)锄俄。如果存在鏡像存檔局劲,則可以在<otherArchives>
下指定它們。 -
post
:用于向郵件列表發(fā)送郵件的電子郵件地址奶赠。請(qǐng)注意鱼填,并非所有郵件列表都能夠發(fā)送到(例如構(gòu)建失敗列表)。
SCM
SCM(Software Configuration Management毅戈,也稱為 Source Code/Control Management 苹丸,或簡(jiǎn)而言之就是版本控制)是任何健康項(xiàng)目的一個(gè)組成部分。如果您的 Maven 項(xiàng)目使用 SCM 系統(tǒng)苇经,那么您可以在這里將該信息放入 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<scm>
<connection>scm:svn:http://127.0.0.1/svn/my-project</connection>
<developerConnection>scm:svn:https://127.0.0.1/svn/my-project</developerConnection>
<tag>HEAD</tag>
<url>http://127.0.0.1/websvn/my-project</url>
</scm>
...
</project>
-
connection
、developerConnection
:這兩個(gè)連接元素表示如何通過 Maven 連接到版本控制系統(tǒng)扇单。如果連接需要讀訪問權(quán)限商模,Maven 才能找到源代碼。如果需要更新,則developerConnection
需要提供寫訪問權(quán)限的連接施流。Maven 孵化出了另一個(gè)名為Maven SCM
的項(xiàng)目响疚,它為希望實(shí)現(xiàn)它的任何 SCM 創(chuàng)建了一個(gè)公共 API。最受歡迎的是 CVS 和 Subversion瞪醋,但是忿晕,其他受支持的 SCM 的列表也在不斷增加。所有 SCM 連接都是通過一般的 URL 結(jié)構(gòu)進(jìn)行的银受。scm:[provider]:[provider_specific]
其中
provider
是 SCM 系統(tǒng)的類型践盼。例如,連接到 CVS 存儲(chǔ)庫(kù)可能如下所示:scm:cvs:pserver:127.0.0.1:/cvs/root:my-project
tag
:指定此項(xiàng)目所在的標(biāo)記宾巍。HEAD
(意思是 SCM 根)應(yīng)該是默認(rèn)值咕幻。url
:可公開可瀏覽的存儲(chǔ)庫(kù)。例如蜀漆,通過 ViewCVS谅河。
SCM URL 的常規(guī)格式為:scm:<scm_provider><delimiter><provider_specific_part>
∪范可以使用冒號(hào) :
作為分隔符绷耍,或者,如果您想將冒號(hào)用于其中一個(gè)變量(例如 Windows 路徑)鲜侥,則可以使用管道 |
褂始。以下是已經(jīng)完全實(shí)現(xiàn)的 SCM:
例如,對(duì)于 Git描函,對(duì)于下面的所有 URL崎苗,我們使用冒號(hào) :
作為分隔符。如果對(duì)其中一個(gè)變量(例如 Windows 路徑)使用冒號(hào)舀寓,則使用管道 |
作為分隔符胆数。端口的分隔符在任何情況下都必須是冒號(hào),因?yàn)檫@部分是在 git URL 規(guī)范中指定的互墓。見 git-fetch
的手冊(cè)必尼。
scm:git:git://server_name[:port]/path_to_repository
scm:git:http://server_name[:port]/path_to_repository
scm:git:https://server_name[:port]/path_to_repository
scm:git:ssh://server_name[:port]/path_to_repository
scm:git:file://[hostname]/path_to_repository
示例
scm:git:git://github.com/path_to_repository
scm:git:http://github.com/path_to_repository
scm:git:https://github.com/path_to_repository
scm:git:ssh://github.com/path_to_repository
scm:git:file://localhost/path_to_repository
在某些情況下,讀寫操作必須使用不同的 URL篡撵。例如判莉,如果通過 http 協(xié)議執(zhí)行獲取,但只能通過 ssh 寫入存儲(chǔ)庫(kù)育谬,則可能發(fā)生這種情況券盅。在這種情況下,兩個(gè)URL 都可以寫入 <developerConnection>
元素中膛檀。fetch URL 必須以 [fetch=]
為前綴锰镀,push URL 必須以 [push=]
為前綴娘侍。例如:
<developerConnection>scm:git:[fetch=]http://mywebserver.org/path_to_repository[push=]ssh://username@otherserver:8898/~/repopath.git</developerConnection>
從 Maven SCM 1.3 版開始,我們假設(shè)遠(yuǎn)程倉(cāng)庫(kù)中的分支名稱與當(dāng)前本地分支的名稱相同互站。因此私蕾,無(wú)論何時(shí)調(diào)用必須訪問遠(yuǎn)程倉(cāng)庫(kù)的 maven-scm
操作僵缺,您都應(yīng)該處于該分支上胡桃。換句話說:如果沒有手動(dòng)指定分支,那么每個(gè) git-fetch
磕潮、git-pull
翠胰、git-push
等將始終在遠(yuǎn)程倉(cāng)庫(kù)中的分支上工作,該分支與當(dāng)前本地分支具有相同的分支名稱:
git push pushUrl currentBranch:currentBranch
provider 程序配置在 ${user.home}/.scm/git-settings.xml
中定義自脯。如下所示:
<git-settings xmlns="http://maven.apache.org/SCM/GIT/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SCM/GIT/1.1.0 http://maven.apache.org/xsd/scm-git-1.1.0.xsd">
<revParseDateFormat/>
<traceGitCommand/>
<gitCommand/>
<commitNoVerify/>
</git-settings>
-
revParseDateFormat
:changelog
命令允許的 git 格式之景,默認(rèn)為yyyy-MM-dd HH:mm:ss
。 -
traceGitCommand
:跟蹤 git 命令的執(zhí)行膏潮《凸罚可以是1
、2
焕参、true
或文件位置轻纪。默認(rèn)為空字符串。 -
gitCommand
:git 可執(zhí)行文件的當(dāng)前名稱叠纷。默認(rèn)為git
刻帚。 -
commitNoVerify
:使用選項(xiàng)--no-verify
(可以防止 cygwin 出現(xiàn)尾隨空格問題)。默認(rèn)為false
涩嚣。
Prerequisites
POM 可能有某些先決條件才能正確執(zhí)行崇众。例如,Maven 2.0.3 中可能有一個(gè)補(bǔ)丁航厚,您需要它來使用 sftp 進(jìn)行部署顷歌。在 Maven 3 中,使用 Maven Enforcer 插件的 requireMavenVersion
規(guī)則或其他規(guī)則檢查其他方面幔睬。
在 Maven 2 中眯漩,這里是您為構(gòu)建提供先決條件的地方:如果不滿足這些先決條件,Maven 甚至在開始構(gòu)建之前都會(huì)失敗溪窒。POM 4.0 中唯一作為先決條件存在的元素是 <maven>
元素坤塞,它具有最小的版本號(hào)。它是用 Maven 2 檢查的澈蚌,不再出現(xiàn)在 Maven 3 中摹芙。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<prerequisites>
<maven>2.0.6</maven>
</prerequisites>
...
</project>
Repositories
Repositories 是遵循 Maven 倉(cāng)庫(kù)目錄布局的工件集合。為了成為 Maven 倉(cāng)庫(kù)工件宛瞄,項(xiàng)目的 POM 文件的路徑必須為 $BASE_REPO/groupId/artifactId/version/artifactId-version.pom
浮禾,其中交胚,$BASE_REPO
可以是本地倉(cāng)庫(kù)的文件目錄,也可以是遠(yuǎn)程倉(cāng)庫(kù)中的基本 URL盈电,其余的路徑結(jié)構(gòu)都是相同的蝴簇。
倉(cāng)庫(kù)作為收集和存儲(chǔ)工件的場(chǎng)所存在。每當(dāng)項(xiàng)目依賴某個(gè)工件時(shí)匆帚,Maven 都會(huì)首先嘗試使用指定工件的本地副本熬词。如果本地倉(cāng)庫(kù)中不存在該工件,它將嘗試從遠(yuǎn)程倉(cāng)庫(kù)下載吸重。POM 中的 <repositories>
元素指定要搜索的備用倉(cāng)庫(kù)互拾。
倉(cāng)庫(kù)是 Maven 社區(qū)最強(qiáng)大的功能之一。默認(rèn)情況下嚎幸,Maven 在以下位置搜索中央倉(cāng)庫(kù):https://repo.maven.apache.org/maven2/颜矿,可以在pom.xml 的 repositories
元素中配置其他存儲(chǔ)庫(kù)。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<repositories>
<repository>
<releases>
<enabled>false</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<name>Nexus Snapshots</name>
<id>snapshots-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
...
</pluginRepositories>
...
</project>
-
releases
嫉晶、snapshots
:這些是針對(duì)每種工件類型的策略:版本(releases)或快照(snapshots)骑疆。有了這兩個(gè)集合,POM 就可以在單倉(cāng)庫(kù)中獨(dú)立地更改每種類型的策略替废。例如箍铭,您可能決定僅啟用快照下載,可能是出于開發(fā)目的舶担。 -
enabled
:表示該倉(cāng)庫(kù)是否已啟用相應(yīng)類型(releases
或snapshots
)的工件坡疼,為true
或false
。 -
updatePolicy
:該元素指定嘗試更新的頻率衣陶。Maven 將本地 POM 的時(shí)間戳(存儲(chǔ)在倉(cāng)庫(kù)的 Maven 元數(shù)據(jù)文件中)與遠(yuǎn)程 POM 進(jìn)行比較柄瑰。可以為:always
剪况、daily
教沾、interval:X
((其中 X 是以分鐘為單位的整數(shù))、never
译断。 -
checksumPolicy
:當(dāng) Maven 將文件部署到倉(cāng)庫(kù)時(shí)授翻,它也會(huì)部署相應(yīng)的校驗(yàn)和(checksum)文件。在遇到校驗(yàn)和文件丟失或不一致時(shí)孙咪,您可以選擇使用ignore
堪唐、fail
或warn
之一。 -
layout
:在上面對(duì)存儲(chǔ)庫(kù)的描述中翎蹈,提到它們都遵循一個(gè)通用的布局淮菠。這基本上是正確的。Maven 2 引入的布局是 Maven 2 和 3 使用的存儲(chǔ)庫(kù)的默認(rèn)布局荤堪;然而合陵,Maven 1.x 有一個(gè)不同的布局枢赔。使用此元素可以指定默認(rèn)元素還是傳統(tǒng)元素。
Plugin Repositories
倉(cāng)庫(kù)是兩種主要類型工件的所在地拥知。第一個(gè)工件是作為依賴項(xiàng)的工件踏拜,中央倉(cāng)庫(kù)中大多數(shù)工件都是此類型。另一類工件就是插件低剔,Maven 插件本身就是一種特殊類型的工件速梗。正因?yàn)槿绱耍寮}(cāng)庫(kù)與依賴項(xiàng)倉(cāng)庫(kù)可能是分開的(然后户侥,現(xiàn)實(shí)中兩者分開的并不多)镀琉。在任何情況下峦嗤,<pluginRepositories>
元素的結(jié)構(gòu)都類似于 <repositories>
元素蕊唐。
distributionManagement
<distributionManagement>
的作用就是管理在整個(gè)構(gòu)建過程中生成的工件和支持工件的部署。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<distributionManagement>
...
<downloadUrl>http://mojo.codehaus.org/my-project</downloadUrl>
<status>deployed</status>
</distributionManagement>
...
</project>
-
downloadUrl
:該 URL 是 Maven 上傳部署該 POM 工件的倉(cāng)庫(kù)地址烁设,其他用戶可以從該地址下載該 POM 的工件替梨。 -
status
:就像鳥巢里的小鳥,status 永遠(yuǎn)不應(yīng)該被人手觸摸装黑!原因是 Maven 將在項(xiàng)目傳輸?shù)絺}(cāng)庫(kù)時(shí)將設(shè)置項(xiàng)目的狀態(tài)副瀑。其有效類型如下所示。-
none
:無(wú)特殊狀態(tài)恋谭。這是 POM 的默認(rèn)設(shè)置糠睡。 -
converted
:倉(cāng)庫(kù)的管理員將此 POM 從早期版本轉(zhuǎn)換為 Maven 2。 -
partner
:此工件已與伙伴倉(cāng)庫(kù)同步疚颊。 -
deployed
:到目前為止是最常見的狀態(tài)狈孔,這意味著該工件是通過 Maven 2 或 3 部署的。這是使用命令行部署階段手動(dòng)部署時(shí)得到的結(jié)果材义。 -
verified
:該項(xiàng)目已驗(yàn)證均抽,應(yīng)視為已完成。
-
Repository
<repositories>
元素在 POM 中指定了 Maven 下載遠(yuǎn)程工件以供當(dāng)前項(xiàng)目使用的位置和方式其掂,而 <distributionManagement>
指定了該項(xiàng)目在部署時(shí)到達(dá)遠(yuǎn)程倉(cāng)庫(kù)的位置(以及方式)油挥。如果未定義 <snapshotRepository>
,則 <repository>
元素將用于快照分發(fā)款熬。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<distributionManagement>
<repository>
<uniqueVersion>false</uniqueVersion>
<id>corp1</id>
<name>Corporate Repository</name>
<url>scp://repo/maven2</url>
<layout>default</layout>
</repository>
<snapshotRepository>
<uniqueVersion>true</uniqueVersion>
<id>propSnap</id>
<name>Propellors Snapshots</name>
<url>sftp://propellers.net/maven</url>
<layout>legacy</layout>
</snapshotRepository>
...
</distributionManagement>
...
</project>
-
id
深寥、name
:該id
用于在眾多倉(cāng)庫(kù)中唯一標(biāo)識(shí)該倉(cāng)庫(kù),并且該name
是易讀的形式。 -
uniqueVersion
:采用true
或false
值來表示部署到此倉(cāng)庫(kù)的工件是否應(yīng)該獲得唯一的版本號(hào)舰褪,或者使用地址中定義的版本號(hào)动漾。 -
url
:這是<repository>
元素的核心。它指定了用于將構(gòu)建工件(以及 POM 文件和校驗(yàn)和數(shù)據(jù))傳輸?shù)酱鎯?chǔ)庫(kù)的位置和傳輸協(xié)議负饲。 -
layout
:這些類型和用途與存儲(chǔ)庫(kù)元素中定義的布局元素相同堤魁。它們是默認(rèn)的和遺留的。
Site Distribution
<distributionManagement>
元素不僅負(fù)責(zé)發(fā)布到倉(cāng)庫(kù)返十,還負(fù)責(zé)定義如何部署項(xiàng)目的站點(diǎn)和文檔妥泉。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<distributionManagement>
...
<site>
<id>mojo.website</id>
<name>Mojo Website</name>
<url>scp://beaver.codehaus.org/home/projects/mojo/public_html/</url>
</site>
...
</distributionManagement>
...
</project>
-
id
、name
洞坑、url
:這些元素與上面<distributionManagement>
中的repository
元素中對(duì)應(yīng)元素類似盲链。
Relocation
<project xmlns="http://maven.apache.org/POM/4.0.0"1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<distributionManagement>
...
<relocation>
<groupId>org.apache</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
<message>We have moved the Project under Apache</message>
</relocation>
...
</distributionManagement>
...
</project>
項(xiàng)目不是靜態(tài)的,它們是有生命的東西(或垂死的東西迟杂,視情況而定)刽沾。隨著項(xiàng)目的發(fā)展,一個(gè)常見的現(xiàn)象是排拷,它們可能會(huì)被迫搬到更合適的地方侧漓。例如,當(dāng)您的下一個(gè)非常成功的開源項(xiàng)目在 Apache 保護(hù)傘下運(yùn)行時(shí)监氢,最好讓用戶知道該項(xiàng)目將被重命名為 org.apache:my-project:1.0
布蔗。除了指定新地址外,提供一條解釋原因的消息也是一種很好的形式浪腐。
Profiles
POM 4.0 的一個(gè)新特性是項(xiàng)目能夠根據(jù)構(gòu)建環(huán)境更改設(shè)置纵揍。<profiles>
元素包含可選 <activation>
(profile 觸發(fā)器)和一組對(duì) POM 的更改(如果該 profile 已激活)。例如议街,為測(cè)試環(huán)境構(gòu)建的項(xiàng)目與與最終部署的項(xiàng)目存在許多不同的屬性配置(諸如數(shù)據(jù)庫(kù)連接信息泽谨、關(guān)聯(lián)服務(wù)的訪問地址等)√劁觯或者吧雹,依賴關(guān)系可以根據(jù)所使用的 JDK 版本從不同的倉(cāng)庫(kù)中提取。<profiles>
元素如下所示:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<profiles>
<profile>
<id>test</id>
<activation>...</activation>
<build>...</build>
<modules>...</modules>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<dependencies>...</dependencies>
<reporting>...</reporting>
<dependencyManagement>...</dependencyManagement>
<distributionManagement>...</distributionManagement>
</profile>
</profiles>
</project>
激活
激活是 profile
的關(guān)鍵拾稳。profile
的威力來自于它僅在特定情況下修改基本 POM 的能力吮炕。這些情況通過 <activation>
元素指定。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<profiles>
<profile>
<id>test</id>
<activation>
<activeByDefault>false</activeByDefault>
<jdk>1.5</jdk>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<property>
<name>sparrow-type</name>
<value>African</value>
</property>
<file>
<exists>${basedir}/file2.properties</exists>
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
...
</profile>
</profiles>
</project>
在 Maven 3.2.2 之前访得,當(dāng)滿足一個(gè)或多個(gè)指定標(biāo)準(zhǔn)時(shí)龙亲,激活發(fā)生。遇到第一個(gè)肯定結(jié)果時(shí)悍抑,處理停止鳄炉,配置文件標(biāo)記為活動(dòng)。因?yàn)?Maven 3.2.2 激活發(fā)生在滿足所有指定標(biāo)準(zhǔn)的情況下搜骡。
-
jdk
:activation
在jdk
元素中有一個(gè)內(nèi)置的拂盯、以 Java 為中心的檢查。如果執(zhí)行 Maven 構(gòu)建的 jdk 版本與jdk
元素值中指定的前綴匹配记靡,則該 profile 將激活谈竿。在上面的示例中团驱,1.5.0_06 可以匹配。還支持匹配范圍空凸。有關(guān)支持范圍的更多詳細(xì)信息嚎花,請(qǐng)參閱 maven-enforcer-plugin 插件。 -
os
:該元素可以定義上面所示的一些特定于操作系統(tǒng)的屬性呀洲。有關(guān)操作系統(tǒng)值的更多詳細(xì)信息,請(qǐng)參閱 maven-enforcer-plugins RequireOS 規(guī)則道逗。 -
property
:如果 Maven 檢測(cè)到對(duì)應(yīng)name=value
對(duì)的系統(tǒng)屬性或命令行屬性(一個(gè)可以由${name}
在 POM 中取消引用的值)滓窍,則該 profile 將被激活贰您。 -
file
:最后锦亦,一個(gè)給定的文件名可能通過文件的existence
或missing
來激活該 profile。注意:此元素的插值僅限于${basedir}
令境、系統(tǒng)屬性和請(qǐng)求屬性杠园。
<activation>
元素不是激活 profile 的唯一方式。settings.xml
文件的 activeProfile
元素可能包含 profile 的 id舔庶。也可以通過在命令行的 -P
標(biāo)志(例如 -P codecoverage
)后面的逗號(hào)分隔列表顯式激活抛蚁。
要查看哪個(gè)配置文件將在特定構(gòu)建中激活,請(qǐng)使用 maven-help-plugin惕橙。
mvn help:active-profiles