maven配置詳解

1 setting.xml

maven的配置文件setting.xml存在于兩個地方:

  • 安裝的地方:${M2_HOME}/conf/settings.xml
  • 用戶的目錄:${user.home}/.m2/settings.xml,該目錄可以自己定義

前者稱為全部變量,對操作系統的所有使用者有效;后者為用戶配置,只對當前操作系統的使用者有效。如果兩者共存,內容將會合并,并且用戶配置會覆蓋全局配置。

Maven安裝后,用戶目錄下不會自動生成settings.xml,只有全局配置文件。如果需要創建用戶范圍的settings.xml,可以將安裝路徑下的settings復制到目錄${user.home}/.m2/。Maven默認的settings.xml是一個包含了注釋和例子的模板,可以快速的修改它來達到你的要求。

全局配置一旦更改,所有的用戶都會受到影響,而且如果maven進行升級,所有的配置都會被清除,所以要提前復制和備份${M2_HOME}/conf/settings.xml文件,一般情況下不推薦配置全局的settings.xml。

下面的配置文件對各個節點的含義及作用都有注解。實際應用中,經常使用的是<localRepository>、<servers>、<mirrors>、<profiles>有限幾個節點,其他節點使用默認值足夠應對大部分的應用場景。

關于xmlns屬性的解析可以查看文章:https://zhuanlan.zhihu.com/p/148110873

<?xml version="1.0" encoding="UTF-8"?>
<settings
    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/settings-1.0.0.xsd">

    <!--本地倉庫。該值表示構建系統本地倉庫的路徑。其默認值為${user.home}/.m2/repository。  -->
    <localRepository>usr/local/maven</localRepository>

    <!--Maven是否需要和用戶交互以獲得輸入。如果Maven需要和用戶交互以獲得輸入,則設置成true,反之則應為false。默認為true。 -->
    <interactiveMode>true</interactiveMode>

    <!--Maven是否需要使用plugin-registry.xml文件來管理插件版本。
        如果設置為true,則在{user.home}/.m2下需要有一個plugin-registry.xml來對plugin的版本進行管理
        默認為false。 -->
    <usePluginRegistry>false</usePluginRegistry>

    <!--表示Maven是否需要在離線模式下運行。如果構建系統需要在離線模式下運行,則為true,默認為false。
        當由于網絡設置原因或者安全因素,構建服務器不能連接遠程倉庫的時候,該配置就十分有用。  -->
    <offline>false</offline>

    <!--當插件的組織Id(groupId)沒有顯式提供時,供搜尋插件組織Id(groupId)的列表。
        該元素包含一個pluginGroup元素列表,每個子元素包含了一個組織Id(groupId)。
        當我們使用某個插件,并且沒有在命令行為其提供組織Id(groupId)的時候,Maven就會使用該列表。
        默認情況下該列表包含了org.apache.maven.plugins。 -->

    <pluginGroups>
        <!--plugin的組織Id(groupId)-->
        <pluginGroup>org.codehaus.mojo</pluginGroup>
    </pluginGroups>

    <!--用來配置不同的代理,多代理profiles可以應對筆記本或移動設備的工作環境:通過簡單的設置profile id就可以很容易的更換整個代理配置 -->
    <proxies>
        <!--代理元素包含配置代理時需要的信息 -->
        <proxy>
            <!--代理的唯一定義符,用來區分不同的代理元素。 -->
            <id>myproxy</id>
            <!--該代理是否是激活的那個。true則激活代理。當我們聲明了一組代理,而某個時候只需要激活一個代理的時候,該元素就可以派上用處 -->
            <active>true</active>
            <!--代理的協議。 協議://主機名:端口,分隔成離散的元素以方便配置。 -->
            <protocol>http://…</protocol>
            <!--代理的主機名。協議://主機名:端口,分隔成離散的元素以方便配置。   -->
            <host>proxy.somewhere.com</host>
            <!--代理的端口。協議://主機名:端口,分隔成離散的元素以方便配置。  -->
            <port>8080</port>
            <!--代理的用戶名,用戶名和密碼表示代理服務器認證的登錄名和密碼。  -->
            <username>proxyuser</username>
            <!--代理的密碼,用戶名和密碼表示代理服務器認證的登錄名和密碼。  -->
            <password>somepassword</password>
            <!--不該被代理的主機名列表。該列表的分隔符由代理服務器指定;例子中使用了豎線分隔符,使用逗號分隔也很常見。 -->
            <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
        </proxy>
    </proxies>

    <!--配置服務端的一些設置。一些設置如安全證書不應該和pom.xml一起分發。這種類型的信息應該存在于構建服務器上的settings.xml文件中。 -->
    <servers>
        <!--服務器元素包含配置服務器時需要的信息  -->
        <server>
            <!--這是server的id(注意不是用戶登陸的id),該id與distributionManagement中repository元素的id相匹配。 -->
            <id>server001</id>
            <!--鑒權用戶名。鑒權用戶名和鑒權密碼表示服務器認證所需要的登錄名和密碼。  -->
            <username>my_login</username>
            <!--鑒權密碼 。鑒權用戶名和鑒權密碼表示服務器認證所需要的登錄名和密碼。  -->
            <password>my_password</password>
            <!--鑒權時使用的私鑰位置。和前兩個元素類似,私鑰位置和私鑰密碼指定了一個私鑰的路徑
                (默認是/home/hudson/.ssh/id_dsa)以及如果需要的話,一個密語。
                將來passphrase和password元素可能會被提取到外部,但目前它們必須在settings.xml文件以純文本的形式聲明 -->
            <privateKey>${usr.home}/.ssh/id_dsa</privateKey>
            <!--鑒權時使用的私鑰密碼。 -->
            <passphrase>some_passphrase</passphrase>
            <!--文件被創建時的權限。如果在部署的時候會創建一個倉庫文件或者目錄,這時候就可以使用權限(permission)。
                這兩個元素合法的值是一個三位數字,其對應了unix文件系統的權限,如664,或者775。  -->
            <filePermissions>664</filePermissions>
            <!--目錄被創建時的權限。  -->
            <directoryPermissions>775</directoryPermissions>
            <!--傳輸層額外的配置項  -->
            <configuration></configuration>
        </server>
    </servers>

    <!--為倉庫列表配置的下載鏡像列表。  -->
    <mirrors>
        <!--給定倉庫的下載鏡像。  -->
        <mirror>
            <!--該鏡像的唯一標識符。id用來區分不同的mirror元素。  -->
            <id>planetmirror.com</id>
            <!--鏡像名稱  -->
            <name>PlanetMirror Australia</name>
            <!--該鏡像的URL。構建系統會優先考慮使用該URL,而非使用默認的服務器URL。  -->
            <url>http://downloads.planetmirror.com/pub/maven2</url>
            <!--被鏡像的服務器的id。例如,如果我們要設置了一個Maven中央倉庫(http://repo1.maven.org/maven2)的鏡像,就需要將該元素設置成central。這必須和中央倉庫的id central完全一致。 -->
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

    <!--根據環境參數來調整構建配置的列表。settings.xml中的profile元素是pom.xml中profile元素的裁剪版本。
        它包含了id,activation, repositories, pluginRepositories和 properties元素。
        這里的profile元素只包含這五個子元素是因為這里只關心構建系統這個整體(這正是settings.xml文件的角色定位),而非單獨的項目對象模型設置。
        如果一個settings中的profile被激活,它的值會覆蓋任何其它定義在POM中或者profile.xml中的帶有相同id的profile。  -->
    <profiles>

        <!--根據環境參數來調整的構件的配置 -->
        <profile>
            <!--該配置的唯一標識符。  -->
            <id>test</id>

            <!--自動觸發profile的條件邏輯。Activation是profile的開啟鑰匙。
                如POM中的profile一樣,profile的力量來自于它能夠在某些特定的環境中自動使用某些特定的值;這些環境通過activation元素指定。
                activation元素并不是激活profile的唯一方式。settings.xml文件中的activeProfile元素可以包含profile的id。
                profile也可以通過在命令行,使用-P標記和逗號分隔的列表來顯式的激活(如,-P test)。 -->
            <activation>
                <!--profile默認是否激活的標識 -->
                <activeByDefault>false</activeByDefault>
                <!--activation有一個內建的java版本檢測,如果檢測到jdk版本與期待的一樣,profile被激活。 -->
                <jdk>1.7</jdk>

                <!--當匹配的操作系統屬性被檢測到,profile被激活。os元素可以定義一些操作系統相關的屬性。 -->
                <os>
                    <!--激活profile的操作系統的名字  -->
                    <name>Windows XP</name>
                    <!--激活profile的操作系統所屬家族(如 'windows')   -->
                    <family>Windows</family>
                    <!--激活profile的操作系統體系結構   -->
                    <arch>x86</arch>
                    <!--激活profile的操作系統版本 -->
                    <version>5.1.2600</version>
                </os>

                <!--如果Maven檢測到某一個屬性(其值可以在POM中通過${名稱}引用),其擁有對應的名稱和值,Profile就會被激活。
                    如果值字段是空的,那么存在屬性名稱字段就會激活profile,否則按區分大小寫方式匹配屬性值字段 -->
                <property>
                    <!--激活profile的屬性的名稱 -->
                    <name>mavenVersion</name>
                    <!--激活profile的屬性的值  -->
                    <value>2.0.3</value>
                </property>

                <!--提供一個文件名,通過檢測該文件的存在或不存在來激活profile。missing檢查文件是否存在,如果不存在則激活profile。
                    另一方面,exists則會檢查文件是否存在,如果存在則激活profile。 -->
                <file>
                    <!--如果指定的文件存在,則激活profile。  -->
                    <exists>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</exists>
                    <!--如果指定的文件不存在,則激活profile。 -->
                    <missing>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</missing>
                </file>
            </activation>

            <!--對應profile的擴展屬性列表。Maven屬性和Ant中的屬性一樣,可以用來存放一些值。這些值可以在POM中的任何地方使用標記${X}來使用,這里X是指屬性的名稱。
                屬性有五種不同的形式,并且都能在settings.xml文件中訪問。   
                   1\. env.X: 在一個變量前加上"env."的前綴,會返回一個shell環境變量。例如,"env.PATH"指代了$path環境變量(在Windows上是%PATH%)。   
                   2\. project.x:指代了POM中對應的元素值。      
                   3\. settings.x: 指代了settings.xml中對應元素的值。   
                   4\. Java System Properties: 所有可通過java.lang.System.getProperties()訪問的屬性都能在POM中使用該形式訪問,   
                    如/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre。      
                   5\. x: 在<properties/>元素中,或者外部文件中設置,以${someVar}的形式使用。  -->
            <properties>
                <!-- 如果這個profile被激活,那么屬性${user.install}就可以被訪問了 -->
                <user.install>usr/local/winner/jobs/maven-guide</user.install>
            </properties>

            <!--遠程倉庫列表,它是Maven用來填充構建系統本地倉庫所使用的一組遠程項目。  -->
            <repositories>
                <!--包含需要連接到遠程倉庫的信息  -->
                <repository>
                    <!--遠程倉庫唯一標識 -->
                    <id>codehausSnapshots</id>
                    <!--遠程倉庫名稱  -->
                    <name>Codehaus Snapshots</name>

                    <!--如何處理遠程倉庫里發布版本的下載 -->
                    <releases>
                        <!--true或者false表示該倉庫是否為下載某種類型構件(發布版,快照版)開啟。   -->
                        <enabled>false</enabled>
                        <!--該元素指定更新發生的頻率。Maven會比較本地POM和遠程POM的時間戳。這里的選項是:
                            always(一直),daily(默認,每日),interval:X(這里X是以分鐘為單位的時間間隔),或者never(從不)。  -->
                        <updatePolicy>always</updatePolicy>
                        <!--當Maven驗證構件校驗文件失敗時該怎么做:
                            ignore(忽略),fail(失敗),或者warn(警告)。 -->
                        <checksumPolicy>warn</checksumPolicy>
                    </releases>

                    <!--如何處理遠程倉庫里快照版本的下載。有了releases和snapshots這兩組配置,POM就可以在每個單獨的倉庫中,為每種類型的構件采取不同的策略。
                        例如,可能有人會決定只為開發目的開啟對快照版本下載的支持。參見repositories/repository/releases元素 -->
                    <snapshots>
                        <enabled />
                        <updatePolicy />
                        <checksumPolicy />
                    </snapshots>

                    <!--遠程倉庫URL,按protocol://hostname/path形式  -->
                    <url>http://snapshots.maven.codehaus.org/maven2</url>

                    <!--用于定位和排序構件的倉庫布局類型-可以是default(默認)或者legacy(遺留)。
                        Maven 2為其倉庫提供了一個默認的布局;然而,Maven 1.x有一種不同的布局。我們可以使用該元素指定布局是default(默認)還是legacy(遺留)。  -->
                    <layout>default</layout>
                </repository>
            </repositories>

            <!--發現插件的遠程倉庫列表。倉庫是兩種主要構件的家。第一種構件被用作其它構件的依賴。這是中央倉庫中存儲的大部分構件類型。另外一種構件類型是插件。
                Maven插件是一種特殊類型的構件。由于這個原因,插件倉庫獨立于其它倉庫。pluginRepositories元素的結構和repositories元素的結構類似。
                每個pluginRepository元素指定一個Maven可以用來尋找新插件的遠程地址。 -->
            <pluginRepositories>
                <!--包含需要連接到遠程插件倉庫的信息.參見profiles/profile/repositories/repository元素的說明 -->
                <pluginRepository>
                    <releases>
                        <enabled />
                        <updatePolicy />
                        <checksumPolicy />
                    </releases>
                    <snapshots>
                        <enabled />
                        <updatePolicy />
                        <checksumPolicy />
                    </snapshots>
                    <id />
                    <name />
                    <url />
                    <layout />
                </pluginRepository>
            </pluginRepositories>

            <!--手動激活profiles的列表,按照profile被應用的順序定義activeProfile。 該元素包含了一組activeProfile元素,每個activeProfile都含有一個profile id。
                任何在activeProfile中定義的profile id,不論環境設置如何,其對應的 profile都會被激活。
                如果沒有匹配的profile,則什么都不會發生。例如,env-test是一個activeProfile,則在pom.xml(或者profile.xml)中對應id的profile會被激活。
                如果運行過程中找不到這樣一個profile,Maven則會像往常一樣運行。  -->
            <activeProfiles>
                <activeProfile>env-test</activeProfile>
            </activeProfiles>
        </profile>
    </profiles>
</settings>

2.pom.xml

settings.xml文件主要用于配置maven運行環境等一系列通用屬性,是全局級別的配置文件,pom.xml文件描述了項目的maven坐標、依賴關系等,開發者需要遵循的規則,缺陷管理系統,組織和licenses,以及其他所有的項目相關因素,是項目級別的配置文件。

2.1 基礎配置

一個典型的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">

    <!-- 模型版本。maven2.0必須是這樣寫,現在是maven2唯一支持的版本 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 公司或者組織的唯一標志,并且配置時生成的路徑也是由此生成,
        如com.winner.trade,maven會將該項目打成的jar包放本地路徑:/com/winner/trade -->
    <groupId>com.winner.trade</groupId>

    <!-- 本項目的唯一ID,一個groupId下面可能多個項目,就是靠artifactId來區分的 -->
    <artifactId>trade-core</artifactId>

    <!-- 本項目目前所處的版本號 -->
    <version>1.0.0-SNAPSHOT</version>

    <!-- 打包的機制,如pom, jar, maven-plugin, ejb, war, ear, rar, par,默認為jar -->
    <packaging>jar</packaging>

    <!-- 幫助定義構件輸出的一些附屬構件,附屬構件與主構件對應,有時候需要加上classifier才能唯一的確定該構件
            不能直接定義項目的classifer,因為附屬構件不是項目直接默認生成的,而是由附加的插件幫助生成的  -->
    <classifier>...</classifier>

    <!-- 定義本項目的依賴關系 -->
    <dependencies>

        <!-- 每個dependency都對應這一個jar包 -->
        <dependency>

            <!-- 一般情況下,maven是通過groupId、artifactId、version這三個元素值(俗稱坐標)來檢索該構件,
                然后引入你的工程。如果別人想引用你現在開發的這個項目(前提是已開發完畢并發布到了遠程倉庫),
                就需要在他的pom文件中新建一個dependency節點,將本項目的groupId、artifactId、version寫入,
                maven就會把你上傳的jar包下載到他的本地 -->
            <groupId>com.winner.trade</groupId>
            <artifactId>trade-test</artifactId>
            <version>1.0.0-SNAPSHOT</version>

            <!-- maven認為,程序對外部的依賴會隨著程序的所處階段和應用場景而變化,所以maven中的依賴關系有作用域(scope)的限制。
                scope包含如下的取值:compile(編譯范圍)、provided(已提供范圍)、runtime(運行時范圍)、test(測試范圍)、system(系統范圍) -->
            <scope>test</scope>

            <!-- 設置指依賴是否可選,默認為false,即子項目默認都繼承:為true,則子項目必需顯示的引入,與dependencyManagement里定義的依賴類似 。 -->
            <optional>false</optional>

            <!-- 屏蔽依賴關系。
                比如項目中使用的libA依賴某個庫的1.0版,libB依賴某個庫的2.0版,現在想統一使用2.0版,就應該屏蔽掉對1.0版的依賴 -->
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!-- 為pom定義一些常量,在pom中的其它地方可以直接引用
        使用方式 如下 :${file.encoding} -->
    <properties>
        <file.encoding>UTF-8</file.encoding>
        <java.source.version>1.5</java.source.version>
        <java.target.version>1.5</java.target.version>
    </properties>

    ...

</project>

上面的配置定義了項目的基本屬性。

2.1.1 dependencies

dependencies屬性是項目相關依賴的配置,如果在父項目寫的依賴,會被子項目引用。一般會在父項目中定義子項目中所有的共用的依賴。

2.1.2 parent

parent屬性用于確認父項目的坐標位置。

<parent>
    <groupId>com.learnPro</groupId>
    <artifactId>SIP-parent</artifactId>
    <relativePath></relativePath>
    <version>0.0.1-SNAPSHOT</version>
</parent>

groupId: 父項目的組Id標識符 artifactId:父項目的唯一標識符 relativePath:Maven首先在當前項目中找父項目的pom,然后在文件系統的這個位置(relativePath),然后在本地倉庫,再在遠程倉庫找。 version: 父項目的版本

2.1.3 modules

有些maven項目會作為多模塊,如SpringMVC項目就分為dal/service/controller三個模塊,這個標簽就是用于指定當前項目所包含的所有模塊。之后對這個項目進行的maven操作就是對所有子模塊進行相同操作。

<modules>
   <module>com-dal</>
   <module>com-service</>
   <module>com-controller</>
<modules/>

2.1.4 properties

properties屬性用于定于pom常亮,如一些依賴的版本號等。

<properties>
    <java.version>1.7</java.version>
</properties>

此時可以在pom文件任意地方使用${Java.version}進行引用指定版本號。

2.1.5 dependencyManagement

在父模塊中定義后,子模塊不會直接使用對應依賴,但是在使用相同依賴的時候可以不加版本號,這樣的好處是,父項目統一了版本,而且子項目可以在需要的時候才引用對應的依賴。

父項目:
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子項目:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
</dependency>

2.1.6 classifier

classifier元素用來幫助定義構建輸出的一些附屬構件。附屬構件與主構件對應,比如主構件是 kimi-app-2.0.0.jar,該項目可能還會通過使用一些插件生成 如 kimi-app-2.0.0-javadoc.jar (Java文檔)、 kimi-app-2.0.0-sources.jar(Java源代碼) 這樣兩個附屬構件。這時候,javadoc、sources就是這兩個附屬構件的classifier,這樣附屬構件也就擁有了自己唯一的坐標。

classifier的用途在于:

  • maven download javadoc / sources jar包的時候,需要借助classifier指明要下載那個附屬構件
  • 引入依賴的時候,有時候僅憑groupId、artifactId、version無法唯一的確定某個構件,需要借助classifier來進一步明確目標。比如JSON-lib,有時候會同一個版本會提供多個jar包,此時可以用于指定java版本。
<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier> 
</dependency>

2.2 構建配置

<build>

    <!-- 產生的構件的文件名,默認值是${artifactId}-${version}。 --> 
    <finalName>myPorjectName</finalName> 

    <!-- 構建產生的所有文件存放的目錄,默認為${basedir}/target,即項目根目錄下的target --> 
    <directory>${basedir}/target</directory> 

    <!-- 當項目沒有規定目標(Maven2 叫做階段(phase))時的默認值,
        必須跟命令行上的參數相同例如jar:jar,或者與某個階段(phase)相同例如install、compile等 --> 
    <defaultGoal>install</defaultGoal>

    <!-- 當filtering開關打開時,使用到的過濾器屬性文件列表。
        項目配置信息中諸如${spring.version}之類的占位符會被屬性文件中的實際值替換掉 --> 
    <filters>
            <filter>../filter.properties</filter>
    </filters> 

    <!-- 項目相關的所有資源路徑列表,例如和項目相關的配置文件、屬性文件,這些資源被包含在最終的打包文件里。 --> 
    <resources> 
        <resource> 

            <!-- 描述了資源的目標路徑。該路徑相對target/classes目錄(例如${project.build.outputDirectory})。
            舉個例子,如果你想資源在特定的包里(org.apache.maven.messages),你就必須該元素設置為org/apache/maven/messages。
            然而,如果你只是想把資源放到源碼目錄結構里,就不需要該配置。 --> 
            <targetPath>resources</targetPath> 

            <!-- 是否使用參數值代替參數名。參數值取自properties元素或者文件里配置的屬性,文件在filters元素里列出。 --> 
            <filtering>true</filtering> 

            <!-- 描述存放資源的目錄,該路徑相對POM路徑 --> 
            <directory>src/main/resources</directory> 

            <!-- 包含的模式列表 --> 
            <includes>  
                <include>**/*.properties</include>  
                <include>**/*.xml</include>  
            </includes>  

            <!-- 排除的模式列表
                如果<include>與<exclude>劃定的范圍存在沖突,以<exclude>為準 --> 
            <excludes>  
                <exclude>jdbc.properties</exclude>  
                </excludes> 

        </resource> 
    </resources> 

    <!-- 單元測試相關的所有資源路徑,配制方法與resources類似--> 
    <testResources> 
        <testResource> 
            <targetPath /><filtering /><directory /><includes /><excludes /> 
        </testResource> 
    </testResources> 

    <!-- 項目源碼目錄,當構建項目的時候,構建系統會編譯目錄里的源碼。該路徑是相對于pom.xml的相對路徑。 --> 
    <sourceDirectory>${basedir}\src\main\java</sourceDirectory> 

    <!-- 項目腳本源碼目錄,該目錄和源碼目錄不同,
        絕大多數情況下,該目錄下的內容會被拷貝到輸出目錄(因為腳本是被解釋的,而不是被編譯的)。 --> 
    <scriptSourceDirectory>${basedir}\src\main\scripts</scriptSourceDirectory>

    <!-- 項目單元測試使用的源碼目錄,當測試項目的時候,構建系統會編譯目錄里的源碼。該路徑是相對于pom.xml的相對路徑。 --> 
    <testSourceDirectory>${basedir}\src\test\java</testSourceDirectory>

    <!-- 被編譯過的應用程序class文件存放的目錄。 --> 
    <outputDirectory>${basedir}\target\classes</outputDirectory>

    <!-- 被編譯過的測試class文件存放的目錄。 --> 
    <testOutputDirectory>${basedir}\target\test-classes</testOutputDirectory> 

    <!-- 項目的一系列構建擴展,它們是一系列build過程中要使用的產品,會包含在running bulid‘s classpath里面。
        他們可以開啟extensions,也可以通過提供條件來激活plugins。
        簡單來講,extensions是在build過程被激活的產品--> 
    <extensions> 

        <!-- 例如,通常情況下,程序開發完成后部署到線上Linux服務器,可能需要經歷打包、
            將包文件傳到服務器、SSH連上服務器、敲命令啟動程序等一系列繁瑣的步驟。
            實際上這些步驟都可以通過Maven的一個插件 wagon-maven-plugin 來自動完成
            下面的擴展插件wagon-ssh用于通過SSH的方式連接遠程服務器,
            類似的還有支持ftp方式的wagon-ftp插件 --> 
        <extension> 
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension> 

    </extensions> 

    <!-- 使用的插件列表 。 --> 
    <plugins> 
        <plugin> 
            <groupId></groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.5.5</version>

            <!-- 在構建生命周期中執行一組目標的配置。每個目標可能有不同的配置。 --> 
            <executions>
                <execution>

                        <!-- 執行目標的標識符,用于標識構建過程中的目標,或者匹配繼承過程中需要合并的執行目標 --> 
                    <id>assembly</id>

                    <!-- 綁定了目標的構建生命周期階段,如果省略,目標會被綁定到源數據里配置的默認階段 --> 
                    <phase>package</phase>

                    <!-- 配置的執行目標 --> 
                    <goals>
                        <goal>single</goal>
                    </goals>

                    <!-- 配置是否被傳播到子POM --> 
                    <inherited>false</inherited> 

                </execution>
            </executions>

            <!-- 作為DOM對象的配置,配置項因插件而異 -->
            <configuration>
                <finalName>${finalName}</finalName>
                <appendAssemblyId>false</appendAssemblyId>
                <descriptor>assembly.xml</descriptor>
            </configuration>

            <!-- 是否從該插件下載Maven擴展(例如打包和類型處理器),
                由于性能原因,只有在真需要下載時,該元素才被設置成true。 --> 
            <extensions>false</extensions> 

            <!-- 項目引入插件所需要的額外依賴 --> 
            <dependencies> 
                <dependency>...</dependency> 
            </dependencies> 

            <!-- 任何配置是否被傳播到子項目 --> 
            <inherited>true</inherited>

        </plugin> 
    </plugins> 

    <!-- 主要定義插件的共同元素、擴展元素集合,類似于dependencyManagement,
        所有繼承于此項目的子項目都能使用。該插件配置項直到被引用時才會被解析或綁定到生命周期。
        給定插件的任何本地配置都會覆蓋這里的配置 --> 
    <pluginManagement> 
        <plugins>...</plugins>
    </pluginManagement>

</build>

pom里面的倉庫與settings.xml倉庫功能一致,主要區別在于:pom倉庫是個性化,比如說大公司的setting文件是公用的,所有項目全部使用同一個settings文件,但是各自項目卻會引用不同的第三方庫,所以就需要在pom設置自己需要的倉庫地址。

2.3 分發配置

<!-- 項目分發信息,在執行mvn deploy后表示要發布的位置。
    有了這些信息就可以把網站部署到遠程服務器或者把構件部署到遠程倉庫。 --> 
<distributionManagement> 

    <!-- 部署項目產生的構件到遠程倉庫需要的信息 --> 
    <repository> 

        <!-- 是分配給快照一個唯一的版本號(由時間戳和構建流水號),還是每次都使用相同的版本號
            參見repositories/repository元素 --> 
        <uniqueVersion>true</uniqueVersion> 

        <id> repo-id </id> 
        <name> repo-name </name> 
        <url> file://${basedir}/target/deploy </url> 
        <layout /> 

    </repository> 

    <!-- 構件的快照部署到哪里,如果沒有配置該元素,默認部署到repository元素配置的倉庫 --> 
    <snapshotRepository> 
        <uniqueVersion /> 
        <id />
        <name /> 
        <url /> 
        <layout /> 
    </snapshotRepository> 

    <!-- 部署項目的網站需要的信息 --> 
    <site> 

        <!-- 部署位置的唯一標識符,用來匹配站點和settings.xml文件里的配置 --> 
        <id> site-id </id> 

        <!-- 部署位置的名稱 --> 
        <name> site-name </name> 

        <!-- 部署位置的URL,按protocol://hostname/path形式 --> 
        <url> scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web </url> 

    </site> 

    <!-- 項目下載頁面的URL。如果沒有該元素,用戶應該參考主頁。
        使用該元素的原因是:幫助定位那些不在倉庫里的構件(由于license限制)。 --> 
    <downloadUrl /> 

    <!-- 如果構件有了新的group ID和artifact ID(構件移到了新的位置),這里列出構件的重定位信息。 --> 
    <relocation> 

        <!-- 構件新的group ID --> 
        <groupId /> 

        <!-- 構件新的artifact ID --> 
        <artifactId /> 

        <!-- 構件新的版本號 --> 
        <version /> 

        <!-- 顯示給用戶的,關于移動的額外信息,例如原因。 --> 
        <message /> 

    </relocation> 

    <!-- 給出該構件在遠程倉庫的狀態。不得在本地項目中設置該元素,因為這是工具自動更新的。有效的值有:none(默認),converted(倉庫管理員從Maven 1 POM轉換過來),partner(直接從伙伴Maven 2倉庫同步過來),deployed(從Maven 2實例部署),verified(被核實時正確的和最終的)。 --> 
    <status /> 

</distributionManagement>

2.4 倉庫配置

<!-- 發現依賴和擴展的遠程倉庫列表。 --> 
<repositories> 

    <!-- 包含需要連接到遠程倉庫的信息 --> 
    <repository> 

        <!-- 如何處理遠程倉庫里發布版本的下載 --> 
        <releases> 

            <!-- true或者false表示該倉庫是否為下載某種類型構件(發布版,快照版)開啟。 --> 
            <enabled /> 

            <!-- 該元素指定更新發生的頻率。Maven會比較本地POM和遠程POM的時間戳。
                這里的選項是:always(一直),daily(默認,每日),
                interval:X(這里X是以分鐘為單位的時間間隔),或者never(從不)。 --> 
            <updatePolicy /> 

            <!-- 當Maven驗證構件校驗文件失敗時該怎么做:
                ignore(忽略),fail(失敗),或者warn(警告)。 --> 
            <checksumPolicy /> 

        </releases> 

        <!-- 如何處理遠程倉庫里快照版本的下載。有了releases和snapshots這兩組配置,
            POM就可以在每個單獨的倉庫中,為每種類型的構件采取不同的策略。
            例如,可能有人會決定只為開發目的開啟對快照版本下載的支持 --> 
        <snapshots> 
            <enabled /><updatePolicy /><checksumPolicy /> 
        </snapshots> 

        <!-- 遠程倉庫唯一標識符。可以用來匹配在settings.xml文件里配置的遠程倉庫 --> 
        <id> repo-id </id> 

        <!-- 遠程倉庫名稱 --> 
        <name> repo-name </name> 

        <!-- 遠程倉庫URL,按protocol://hostname/path形式 --> 
        <url> http://192.168.1.169:9999/repository/ </url> 

        <!-- 用于定位和排序構件的倉庫布局類型-可以是default(默認)或者legacy(遺留)。
            Maven 2為其倉庫提供了一個默認的布局;
            然而,Maven 1.x有一種不同的布局。
            我們可以使用該元素指定布局是default(默認)還是legacy(遺留)。 --> 
        <layout> default </layout> 

    </repository> 

</repositories> 

<!-- 發現插件的遠程倉庫列表,這些插件用于構建和報表 --> 
<pluginRepositories> 

    <!-- 包含需要連接到遠程插件倉庫的信息.參見repositories/repository元素 --> 
    <pluginRepository /> 

</pluginRepositories>

2.5 報表配置

reporting元素描述使用報表插件產生報表的規范。當用戶執行“mvn site”,這些報表就會運行。 在頁面導航欄能看到所有報表的鏈接。

<!-- 描述使用報表插件產生報表的規范,特定的maven 插件能輸出相應的定制和配置報表.
當用戶執行“mvn site”,這些報表就會運行,在頁面導航欄能看到所有報表的鏈接。 --> 
<reporting> 

    <!-- true,則網站不包括默認的報表。這包括“項目信息”菜單中的報表。 --> 
    <excludeDefaults /> 

    <!-- 所有產生的報表存放到哪里。默認值是${project.build.directory}/site。 --> 
    <outputDirectory /> 

    <!-- 使用的報表插件和他們的配置。 --> 
    <plugins> 

        <plugin> 
            <groupId /> 
            <artifactId />
            <version />
            <inherited />
            <configuration> 
                <links> 
                    <link>http://java.sun.com/j2se/1.5.0/docs/api/</link> 
                </links> 
            </configuration>
            <!-- 一組報表的多重規范,每個規范可能有不同的配置。
            一個規范(報表集)對應一個執行目標 。例如,有1,2,3,4,5,6,7,8,9個報表。
            1,2,5構成A報表集,對應一個執行目標。2,5,8構成B報表集,對應另一個執行目標 --> 
            <reportSets> 

                <!-- 表示報表的一個集合,以及產生該集合的配置 --> 
                <reportSet> 

                    <!-- 報表集合的唯一標識符,POM繼承時用到 --> 
                    <id>sunlink</id> 

                    <!-- 產生報表集合時,被使用的報表的配置 --> 
                    <configuration /> 

                    <!-- 配置是否被繼承到子POMs --> 
                    <inherited /> 

                    <!-- 這個集合里使用到哪些報表 --> 
                    <reports>
                        <report>javadoc</report>  
                    </reports>

                </reportSet> 

            </reportSets> 

        </plugin> 

    </plugins> 

</reporting>    

2.6 項目配置

<!-- 項目的問題管理系統(Bugzilla, Jira, Scarab,或任何你喜歡的問題管理系統)的名稱和URL,本例為 jira --> 
<issueManagement> 

    <!-- 問題管理系統(例如jira)的名字, --> 
    <system> jira </system> 

    <!-- 該項目使用的問題管理系統的URL --> 
    <url> http://jira.clf.com/ </url> 

</issueManagement> 

<!-- 項目持續集成信息 --> 
<ciManagement> 

    <!-- 持續集成系統的名字,例如continuum --> 
    <system>continumm</system> 

    <!-- 該項目使用的持續集成系統的URL(如果持續集成系統有web接口的話)。 --> 
    <url>http://127.0.0.1:8080/continuum</url>

    <!-- 構建完成時,需要通知的開發者/用戶的配置項。包括被通知者信息和通知條件(錯誤,失敗,成功,警告) --> 
    <notifiers> 

        <!-- 配置一種方式,當構建中斷時,以該方式通知用戶/開發者 --> 
        <notifier> 

            <!-- 傳送通知的途徑 --> 
            <type /> 

            <!-- 發生錯誤時是否通知 --> 
            <sendOnError /> 

            <!-- 構建失敗時是否通知 --> 
            <sendOnFailure /> 

            <!-- 構建成功時是否通知 --> 
            <sendOnSuccess /> 

            <!-- 發生警告時是否通知 --> 
            <sendOnWarning /> 

            <!-- 不贊成使用。通知發送到哪里 --> 
            <address /> 

            <!-- 擴展配置項 --> 
            <configuration /> 

        </notifier> 

    </notifiers> 

</ciManagement>

<!-- 項目的名稱, Maven產生的文檔用 --> 
<name> banseon-maven </name> 

<!-- 項目主頁的URL, Maven產生的文檔用 --> 
<url> http://www.clf.com/ </url> 

<!-- 項目的詳細描述, Maven 產生的文檔用。 當這個元素能夠用HTML格式描述時
    (例如,CDATA中的文本會被解析器忽略,就可以包含HTML標簽),不鼓勵使用純文本描述。
    如果你需要修改產生的web站點的索引頁面,你應該修改你自己的索引頁文件,而不是調整這里的文檔。 --> 
<description> A maven project to study maven. </description> 

<!-- 描述了這個項目構建環境中的前提條件。 --> 
<prerequisites> 

    <!-- 構建該項目或使用該插件所需要的Maven的最低版本 --> 
    <maven /> 

</prerequisites> 

<!-- 項目創建年份,4位數字。當產生版權信息時需要使用這個值。 --> 
<inceptionYear /> 

<!-- 項目相關郵件列表信息 --> 
<mailingLists> 

    <!-- 該元素描述了項目相關的所有郵件列表。自動產生的網站引用這些信息。 --> 
    <mailingList> 

        <!-- 郵件的名稱 --> 
        <name> Demo </name> 

        <!-- 發送郵件的地址或鏈接,如果是郵件地址,創建文檔時,mailto: 鏈接會被自動創建 --> 
        <post> clf@126.com </post> 

        <!-- 訂閱郵件的地址或鏈接,如果是郵件地址,創建文檔時,mailto: 鏈接會被自動創建 --> 
        <subscribe> clf@126.com </subscribe> 

        <!-- 取消訂閱郵件的地址或鏈接,如果是郵件地址,創建文檔時,mailto: 鏈接會被自動創建 --> 
        <unsubscribe> clf@126.com </unsubscribe> 

        <!-- 你可以瀏覽郵件信息的URL --> 
        <archive> http:/hi.clf.com/ </archive> 

    </mailingList> 

</mailingLists> 

<!-- 項目開發者列表 --> 
<developers> 

    <!-- 某個項目開發者的信息 --> 
    <developer> 

        <!-- SCM里項目開發者的唯一標識符 --> 
        <id> HELLO WORLD </id> 

        <!-- 項目開發者的全名 --> 
        <name> banseon </name> 

        <!-- 項目開發者的email --> 
        <email> banseon@126.com </email> 

        <!-- 項目開發者的主頁的URL --> 
        <url /> 

        <!-- 項目開發者在項目中扮演的角色,角色元素描述了各種角色 --> 
        <roles> 
            <role> Project Manager </role> 
            <role> Architect </role> 
        </roles> 

        <!-- 項目開發者所屬組織 --> 
        <organization> demo </organization> 

        <!-- 項目開發者所屬組織的URL --> 
        <organizationUrl> http://hi.clf.com/ </organizationUrl> 

        <!-- 項目開發者屬性,如即時消息如何處理等 --> 
        <properties> 
            <dept> No </dept> 
        </properties> 

        <!-- 項目開發者所在時區, -11到12范圍內的整數。 --> 
        <timezone> -5 </timezone> 

    </developer> 

</developers> 

<!-- 項目的其他貢獻者列表 --> 
<contributors> 

    <!-- 項目的其他貢獻者。參見developers/developer元素 --> 
    <contributor> 
        <name /><email /><url /><organization /><organizationUrl />
        <roles /><timezone /><properties /> 
    </contributor> 

</contributors> 

<!-- 該元素描述了項目所有License列表。應該只列出該項目的license列表,不要列出依賴項目的license列表。
    如果列出多個license,用戶可以選擇它們中的一個而不是接受所有license。 --> 
<licenses> 

    <!-- 描述了項目的license,用于生成項目的web站點的license頁面,其他一些報表和validation也會用到該元素。 --> 
    <license> 

        <!-- license用于法律上的名稱 --> 
        <name> Apache 2 </name> 

        <!-- 官方的license正文頁面的URL --> 
        <url> http://www.clf.com/LICENSE-2.0.txt </url> 

        <!-- 項目分發的主要方式: 
        repo,可以從Maven庫下載 
        manual, 用戶必須手動下載和安裝依賴 --> 
        <distribution> repo </distribution> 

        <!-- 關于license的補充信息 --> 
        <comments> A business-friendly OSS license </comments> 

    </license> 

</licenses> 

<!-- SCM(Source Control Management)標簽允許你配置你的代碼庫,供Maven web站點和其它插件使用。 --> 
<scm> 

    <!-- SCM的URL,該URL描述了版本庫和如何連接到版本庫。欲知詳情,請看SCMs提供的URL格式和列表。該連接只讀。 --> 
    <connection>scm:svn:http://svn.baidu.com/banseon/maven/</connection> 

    <!-- 給開發者使用的,類似connection元素。即該連接不僅僅只讀 --> 
    <developerConnection>scm:svn:http://svn.baidu.com/banseon/maven/</developerConnection> 

    <!-- 當前代碼的標簽,在開發階段默認為HEAD --> 
    <tag /> 

    <!-- 指向項目的可瀏覽SCM庫(例如ViewVC或者Fisheye)的URL。 --> 
    <url> http://svn.baidu.com/banseon </url> 

</scm> 

<!-- 描述項目所屬組織的各種屬性。Maven產生的文檔用 --> 
<organization> 

    <!-- 組織的全名 --> 
    <name> demo </name> 

    <!-- 組織主頁的URL --> 
    <url> http://www.clf.com/ </url> 

</organization>

2.7 profile

pom.xml中的profile可以看做pom.xml的副本,擁有與pom.xml相同的子元素與配置方法。它包含可選的activation(profile的觸發器)和一系列的changes。例如test過程可能會指向不同的數據庫(相對最終的deployment)或者不同的dependencies或者不同的repositories,并且是根據不同的JDK來改變的。只需要其中一個成立就可以激活profile,如果第一個條件滿足了,那么后面就不會在進行匹配。

<!-- 在列的項目構建profile,如果被激活,會修改構建處理 --> 
<profiles> 

    <!-- 根據環境參數或命令行參數激活某個構建處理 --> 
    <profile> 
        <!--自動觸發profile的條件邏輯。Activation是profile的開啟鑰匙。-->
        <activation>

             <!--profile默認是否激活的標識 -->
            <activeByDefault>false</activeByDefault>

             <!--activation有一個內建的java版本檢測,如果檢測到jdk版本與期待的一樣,profile被激活。 -->
            <jdk>1.7</jdk>

             <!--當匹配的操作系統屬性被檢測到,profile被激活。os元素可以定義一些操作系統相關的屬性。 -->
            <os>

                 <!--激活profile的操作系統的名字  -->
                <name>Windows XP</name>

                 <!--激活profile的操作系統所屬家族(如 'windows')   -->
                <family>Windows</family>

                 <!--激活profile的操作系統體系結構   -->
                <arch>x86</arch>

                 <!--激活profile的操作系統版本 -->
                <version>5.1.2600</version>

            </os>

             <!--如果Maven檢測到某一個屬性(其值可以在POM中通過${名稱}引用),其擁有對應的名稱和值,Profile就會被激活。
                如果值字段是空的,那么存在屬性名稱字段就會激活profile,否則按區分大小寫方式匹配屬性值字段 -->
            <property>

                 <!--激活profile的屬性的名稱 -->
                <name>mavenVersion</name>

                 <!--激活profile的屬性的值  -->
                <value>2.0.3</value>

            </property>

             <!--提供一個文件名,通過檢測該文件的存在或不存在來激活profile。missing檢查文件是否存在,如果不存在則激活profile。
                另一方面,exists則會檢查文件是否存在,如果存在則激活profile。 -->
            <file>

                 <!--如果指定的文件存在,則激活profile。  -->
                <exists>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</exists>

                 <!--如果指定的文件不存在,則激活profile。 -->
                <missing>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</missing>

            </file>

        </activation>
        <id /> 
        <build />
        <modules /> 
        <repositories /> 
        <pluginRepositories /> 
        <dependencies /> 
        <reporting /> 
        <dependencyManagement /> 
        <distributionManagement /> 
        <properties /> 
    </profile>
</profiles>

profile可以讓maven能夠自動適應外部的環境變化,比如同一個項目,在linux下編譯linux的版本,在win下編譯win的版本等。一個項目可以設置多個profile,也可以在同一時間設置多個profile被激活(active)的。自動激活的 profile的條件可以是各種各樣的設定條件,組合放置在activation節點中,也可以通過命令行直接指定。如果認為profile設置比較復雜,可以將所有的profiles內容移動到專門的 profiles.xml 文件中,不過記得和pom.xml放在一起。

activation節點是設置該profile在什么條件下會被激活,常見的條件有如下幾個.

2.7.1 os

判斷操作系統相關的參數,它包含如下可以自由組合的子節點元素

message - 規則失敗之后顯示的消息
arch - 匹配cpu結構,常見為x86
family - 匹配操作系統家族,常見的取值為:dos,mac,netware,os/2,unix,windows,win9x,os/400等
name - 匹配操作系統的名字
version - 匹配的操作系統版本號
display - 檢測到操作系統之后顯示的信息

2.7.2 jdk

檢查jdk版本,可以用區間表示。

2.7.3 property

檢查屬性值,本節點可以包含name和value兩個子節點。

2.7.4 file

檢查文件相關內容,包含兩個子節點:exists和missing,用于分別檢查文件存在和不存在兩種情況。

如果想要某個profile默認處于激活狀態,可以在<activeProfiles>中將該profile的id放進去。這樣,不論環境設置如何,其對應的 profile都會被激活。

profile配置項在setting.xml中頁有,是pom.xml中profile元素的裁剪版本,包含了id,activation, repositories, pluginRepositories和 properties元素。這里的profile元素只包含這五個子元素是因為setting.xml只關心構建系統這個整體(這正是settings.xml文件的角色定位),而非單獨的項目對象模型設置。如果一個settings中的profile被激活,它的值會覆蓋任何其它定義在POM中或者profile.xml中的帶有相同id的profile。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容