Maven POM 基礎(chǔ)配置

The Basics

??????POM文件包含關(guān)于項目的所有必要信息誓篱,以及在構(gòu)建項目過程中使用的插件配置。
??????它是一個對于"who","what","where"的聲明性表現(xiàn)裁替,而build生命周期是一個"when"和"how"的表現(xiàn)蕾久。但這并不是說POM文件不能影響生命周期的流程,它是可以的新娜。比如通過maven-antrun-plugin配置它可以有效的將Apache Ant任務(wù)嵌入到POM中,然而它只是一個最終的聲明既绩。build.xml會在Ant運行時告訴它做什么(過程中)概龄,pom只是聲明它的配置(聲明)。對于pom來說饲握,如果某些外力導(dǎo)致生命周期跳過Ant插件私杜,它是不會停止那些執(zhí)行中的插件的;而build.xml的任務(wù)總是依賴于之前執(zhí)行的任務(wù)救欧。

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>my-project</artifactId>
  <version>1.0</version>
</project>

Maven坐標(biāo)

??????groupId歪今,artifactId,version都是必填項(如果從父類繼承g(shù)roupId和version颜矿,則不需要顯式地定義它們)。這三個字段很像一個地址和時間戳嫉晶,它們在存儲庫中標(biāo)記了一個特定的位置骑疆,充當(dāng)Maven項目的坐標(biāo)系統(tǒng)田篇。

  • groupId:它在組織或項目中通常是唯一的。

??????groupId并不是必須使用"."分隔(如junit)箍铭,另外使用"."標(biāo)記的groupId也不一定要與項目的包結(jié)構(gòu)相對應(yīng)(不過建議與包結(jié)構(gòu)對應(yīng))泊柬。當(dāng)在存儲倉庫中存儲時,group的行為和在操作系統(tǒng)中的Java包結(jié)構(gòu)非常相似诈火。這些"."被操作系統(tǒng)特定的目錄分隔符替換(如UNIX中的"/")使基礎(chǔ)倉庫變成了相對的目錄結(jié)構(gòu)兽赁。在上面的例子中org.codehaus.mojo組被存儲于$M2_REPO/org/codehaus/mojo目錄下。

  • artifactId:它通常是項目已知的名稱冷守。

??????artifactId和groupId一起創(chuàng)建了一個key值刀崖,用來區(qū)別于世界上其他的項目。它與groupId一起定義了artifact在存儲倉庫中的位置拍摇。在上面的例子中my-project存儲于$M2_REPO/org/codehaus/mojo/my-project目錄亮钦。

  • version:用來指定項目的版本。

??????groupId和artifactId可以表示單個項目充活,但它們無法描述我們正在討論的是該項目的哪一種形式蜂莉。比如我們是想使用2018年的junit:junit(4.12版本)還是2007年的junit:junit(3.8.2版本)?簡而言之:代碼更改混卵,應(yīng)該對這些更改進行版本控制映穗,并且此元素可以使這些版本保持一致。同樣的幕随,它也被用于存儲倉庫中用來區(qū)分不同的版本蚁滋。在上面的例子中my-project最終存儲于$M2_REPO/org/codehaus/mojo/my-project/1.0目錄中。

packaging

??????用來聲明項目的打包方式合陵。若沒有聲明該部分則默認(rèn)打包方式為jar枢赔。當(dāng)前packaging的值有:pom,jar拥知,maven-plugin踏拜,ejb,war低剔,ear速梗,rar

POM依賴關(guān)系

??????Maven一個強大的方面是它對項目關(guān)系的處理,包括依賴項和傳遞依賴項襟齿、繼承和聚合(多model的項目)姻锁。依賴項管理的傳統(tǒng)就是除了最瑣碎的項目之外,其他項目都是一團糟猜欺。隨著依賴樹變得龐大而復(fù)雜位隶,"Jarmageddon"很快就出現(xiàn)了。接下來是"Jar Hell"开皿,在Jar Hell中涧黄,一個系統(tǒng)上依賴的版本與使用它開發(fā)的版本是不相等的篮昧,要么是給出的版本是錯誤的,要么是名稱類似的Jar之間的版本沖突笋妥。Maven通過一個公共的本地存儲庫解決了這兩個問題懊昨,從這個存儲庫可以正確地鏈接項目、版本等春宣。

Dependencies

??????POM的基礎(chǔ)是其dependency列表酵颁。大多數(shù)項目依賴于其他項目才能成功build和運行。Maven會在編譯時下載和鏈接這些dependency和它們依賴的其他目標(biāo)月帝。

  • Maven優(yōu)點:幫助你管理所依賴項目的相關(guān)依賴躏惋,使你只需要關(guān)注自己項目所需的依賴關(guā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">
  ...
  <dependencies>

    <dependency> 
        <!-- 依賴的group ID --> 
        <groupId>org.apache.maven</groupId> 

        <!-- 依賴的artifact ID --> 
        <artifactId>maven-artifact</artifactId> 

        <!-- 依賴的版本號 --> 
        <version>3.8.1</version> 

        <!-- 依賴類型,默認(rèn)類型是jar嫁赏。
             它通常表示依賴的文件的擴展名,但也可以被映射成另外一個擴展名或分類器其掂。
             type經(jīng)常和使用的打包方式對應(yīng)(也有例外)。一些類型的例子:jar,war,ejb-client和test-jar潦蝇。
             如果設(shè)置extensions為true,就可以在plugin里定義新的類型款熬。 --> 
        <type>jar</type> 

        <!-- 依賴的分類器。
             分類器可以區(qū)分屬于同一個POM,但不同構(gòu)建方式的artifact攘乒。分類器名被附加到version后面贤牛。
             例如,如果你想要構(gòu)建兩個單獨的artifact成JAR,一個使用Java1.4編譯器,另一個使用Java6編譯器,
             就可以使用分類器來生成兩個單獨的JAR構(gòu)件。 --> 
        <classifier></classifier> 

        <!-- 依賴范圍则酝。在項目發(fā)布過程中,幫助決定哪些構(gòu)件被包括進來殉簸。欲知詳情請參考依賴機制。 
            - compile :默認(rèn)范圍,用于編譯 
            - provided:類似于編譯,但支持你期待jdk或者容器提供,類似于classpath 
            - runtime: 在執(zhí)行時需要使用 
            - test: 用于test任務(wù)時使用 
            - system: 需要外在提供相應(yīng)的元素沽讹。通過systemPath來取得 
            - systemPath: 僅用于范圍為system般卑。提供相應(yīng)的路徑 
            - optional: 當(dāng)項目自身被依賴時,標(biāo)注依賴是否傳遞。用于連續(xù)依賴時使用 --> 
        <scope>test</scope> 

        <!-- 僅供system范圍使用爽雄。
             注意,不鼓勵使用這個元素,并且在新的版本中該元素可能被覆蓋掉蝠检。
             該元素為依賴規(guī)定了文件系統(tǒng)上的路徑,必須是絕對路徑。
             推薦使用屬性匹配絕對路徑,如${java.home}. --> 
        <systemPath></systemPath> 

        <!-- 當(dāng)計算傳遞依賴時,從依賴構(gòu)件列表里,列出被排除的依賴構(gòu)件集挚瘟。
             即告訴maven你只依賴指定的項目,不依賴項目的依賴叹谁。此元素主要用于解決版本沖突問題 --> 
        <exclusions> 
            <exclusion> 
                <artifactId>spring-core</artifactId> 
                <groupId>org.springframework</groupId> 
            </exclusion> 
        </exclusions> 

        <!-- 可選依賴,如果你在項目B中把C依賴聲明為可選,就需要在依賴于B的項目中顯式的引用對C的依賴。
             可選依賴阻斷依賴的傳遞性乘盖。 --> 
        <optional>true</optional> 
    </dependency> 
    
    ...
  </dependencies>
  ...
</project>
  • groupId焰檩,artifactId,version:

??????此三元組用于及時計算特定項目的Maven坐標(biāo)订框,并將其劃分為該項目的依賴項析苫。這個計算的目的是選擇一個匹配所有依賴聲明的版本(因為依賴是傳遞的,對于同一個artifact可能有多個dependency聲明)。groupId & artifactId:直接指向此依賴的坐標(biāo)衩侥;version:依賴項版本必要說明浪腐,用于計算依賴項的有效版本。
??????由于依賴性是由Maven坐標(biāo)描述的顿乒,所以項目只能依賴于Maven的artifact工作,這迫使你只能依賴那些Maven可以管理的dependency泽谨。
??????有時候無法從Maven中央倉庫下載一個項目璧榄,比如一個項目依賴了一個具有閉源許可證的JAR包,閉源的JAR包Maven中央倉庫是不會存儲的吧雹。有三種方法來處理這種情況:

  1. 使用install插件骨杂,在本地install這些依賴(此方法是最簡單的推薦方法)。例子:
mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar

注意:此處仍然需要一個地址雄卷。只有第一次需要使用命令行搓蚪,然后install插件會根據(jù)給定的地址創(chuàng)建一個POM,此后可以直接引用丁鹉。

  1. 使用自己的倉庫并將其部署在里面妒潭。

??????這是使用企業(yè)內(nèi)部網(wǎng)絡(luò)的公司最喜歡的一種方式,需要使每個人保持同步揣钦。此處使用的Maven命令為deploy:deploy-file雳灾,它與install:install-file使用方式類似

  1. 設(shè)置這個依賴的scope為system并且定義一個systemPath。但是此方式并推薦冯凹,主要為了引出以下屬性:
  • classifier-依賴的分類器:

??????classifier用于區(qū)分從同一個POM構(gòu)建的但內(nèi)容不同的artifact谎亩。它是一些可選的任意字符串,如果存在則被附加到artifact的版本號之后宇姚。
??????例如:一個項目提供了一個針對JRE1.5的artifact匈庭,但同時也仍然支持JRE1.4的artifact。這時就可以使用classifier標(biāo)記一個artifact為jdk15浑劳,另一個為jdk14阱持,這樣使用者就可以選擇使用哪一個。另外一個應(yīng)用場景就是將次要的artifact添加到項目的主artifact上呀洲。如果瀏覽Maven中央倉庫就會注意到classifier"sources"和"javadoc"被用于部署項目源代碼和API文檔以及打包的類文件紊选。

  • type-依賴的類型:

??????對應(yīng)于依賴的類型,默認(rèn)為jar道逗。它通常表示dependency文件的拓展名兵罢,也可以將type映射到不同的extension和classifier。type的值通常對應(yīng)于packaging使用的值滓窍,但是也有例外卖词,如:jar,ejb-client和test-jar,詳情參見:http://maven.apache.org/ref/current/maven-core/artifact-handlers.html此蜈。
PS:新的type可以在extensions為true的plugins中定義即横。

  • scope-依賴的作用域:
    此屬性指的是手頭任務(wù)(編譯、運行和測試等)的類路徑裆赵,以及如何限制依賴的傳遞性东囚。有五個值可用:

    • compile:默認(rèn)作用范圍,當(dāng)未指定時默認(rèn)使用該值战授。編譯期依賴可以在所有的類路徑中使用页藻,并且這些依賴關(guān)系可以被傳播到其他項目。
    • provided:它與compile很相似植兰,但是表示只希望在JDK或容器在運行時提供該依賴份帐。它只在編譯和測試的類路徑上有效,并且是不傳遞的楣导。
    • runtime:該作用域表示編譯期不需要該dependency废境,但是執(zhí)行時需要。它只在運行時和測試的類路徑上有效筒繁,編譯的類路徑中不存在噩凹。
    • test:該作用域表示該dependency正常情況下是非必須的。它只在測試編譯和執(zhí)行階段生效膝晾,是不傳遞的栓始。
    • system:該作用域與provided類似,不過system表示需要顯式的提供它包含的JAR包血当。該artifact總是可用的幻赚,但是不是從存儲倉庫中查找的。
  • systemPath-依賴的系統(tǒng)路徑:

??????當(dāng)且僅當(dāng)dependency的scope值為system時有效臊旭。如果scope的值不是system而設(shè)置了systemPath那么將build失敗落恼。該值指向的路徑必須是絕對路徑,因此建議使用屬性來指定特定于機器的路徑如 ${java.home}/lib离熏。因為假定system作用域的依賴已經(jīng)被安裝了佳谦,所以Maven不會在存儲倉庫中檢查該項目,而是檢查該文件是否存在滋戳,如果不存在則Maven將build失敗并且建議手動下載和安裝它钻蔑。

  • optional-依賴的可選項:

??????當(dāng)不可能(無論出于何種原因)將項目分割為子模塊時,將使用optional依賴項奸鸯。其思想是咪笑,一些依賴項僅用于項目中的某些功能,如果不使用該功能娄涩,就不需要這些依賴項窗怒。理想情況下,這樣的功能應(yīng)該劃分為依賴于核心功能項目的子模塊,這個新的子項目將只有非可選的dependency扬虚。然而努隙,由于項目不能被分割(無論出于什么原因),這些依賴項被聲明為可選的辜昵。如果用戶希望使用與可選依賴項相關(guān)的功能荸镊,則必須在自己的項目中重新聲明該可選依賴項。這不是處理這種情況的最好方法堪置,但是可選的依賴項(optional)和依賴項排除(exclusion)都是權(quán)宜之計贷洲。
??????應(yīng)用場景:optional依賴項可以節(jié)省空間和內(nèi)存,另外它們可以防止有問題的jar(違反許可協(xié)議或?qū)е骂惵窂絾栴})被綁定到WAR晋柱、EAR、fat jar或類似的jar中诵叁。
??????optional的值只支持true或者false

  • exclusions-依賴的排除:

??????exclusions指定了一個依賴項雁竞,它告訴Maven不要將其包含在當(dāng)前依賴項中(這是由于依賴的傳遞性)。比如maven-embedder需要使用maven-core但是我們不希望使用它或者它的依賴項拧额,那么就可以將其排除:

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

??????有時exclusions也可以用來剪掉依賴的傳遞關(guān)系碑诉。一個dependency可能指定了錯誤的作用域,或者與你項目中的其他依賴項沖突侥锦。使用通配符可以很容易地排除所有依賴項的傳遞關(guān)系。下面的例子表示你需要使用maven-embedder但是你希望自己管理它的依賴項,所以就排除了其全部的傳遞依賴:

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

exclusions中包含一個或多個exclusion臼勉,每一個exclusion都包含groupId和artifactId用以表示要排除的依賴漠另。

Inheritance -- 繼承

??????父項目和聚合項目需要的packaging類型是pom。packaging的類型定義了綁定到一組生命周期階段的目標(biāo)番挺。例如唠帝,如果packaging是jar,那么打包(package)階段將執(zhí)行jar:jar目標(biāo)玄柏。父POM中的大多數(shù)元素都可以被其孩子繼承襟衰,包括:

  • groupId
  • version
  • description
  • url
  • inceptionYear(項目創(chuàng)建年份,4位數(shù)字粪摘。當(dāng)產(chǎn)生版權(quán)信息時需要使用這個值)
  • organization(項目開發(fā)者/貢獻者所屬組織)
  • licenses
  • developers(項目開發(fā)者信息)
  • contributors(項目貢獻者信息)
  • mailingLists(項目相關(guān)郵件列表信息)
  • scm(Source Control Management 用來配置代碼庫以供Maven Web站點和其他插件使用)
  • issueManagement(項目的問題管理系統(tǒng))
  • ciManagement(項目持續(xù)集成信息)
  • properties(以值替代名稱瀑晒,Properties可以在整個POM中使用,也可以作為觸發(fā)條件)
  • dependencyManagement(繼承自該項目的所有子項目的默認(rèn)依賴信息徘意。這部分的依賴信息不會被立即解析,而是當(dāng)子項目聲明一個依賴)
  • dependencies
  • repositories(發(fā)現(xiàn)dependency和exclusion的遠程倉庫列表)
  • pluginRepositories(發(fā)現(xiàn)plugin的遠程倉庫列表苔悦,這些插件用于build和report)
  • build
    • plugin executions with matching ids
    • plugin configuration
    • etc.
  • reporting(該元素描述使用report插件產(chǎn)生報表的規(guī)范。當(dāng)用戶執(zhí)行“mvn site”映砖,這些報表就會運行间坐。 在頁面導(dǎo)航欄能看到所有報表的鏈接。)
  • profiles(在列的項目構(gòu)建profile,如果被激活竹宋,會修改build)

不會被繼承的元素:

  • artifactId

  • name

  • prerequisites(描述了這個項目build環(huán)境中的前提條件)

       <!-- 描述了這個項目構(gòu)建環(huán)境中的前提條件劳澄。 --> 
      <prerequisites>
          <!-- 構(gòu)建該項目或使用該插件所需要的Maven的最低版本 -->
          <maven></maven>
      </prerequisites>
    

Super POM

??????類似于面向?qū)ο缶幊讨袑ο蟮睦^承,拓展父pom的那些poms繼承了來自父級的一些值蜈七。另外秒拔,正如Java中的對象最終都是繼承自java.lang.Object一樣,所有的項目的對象模型都是繼承自一個基礎(chǔ)的pom--Super POM飒硅。下面的片段是Maven 3.5.4的Super POM:

<project>
  <modelVersion>4.0.0</modelVersion>

  <!-- 發(fā)現(xiàn)dependency和exclusion的遠程倉庫列表 -->
  <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>
 
  <!-- 發(fā)現(xiàn)插件的遠程倉庫列表砂缩,用于build和report -->
  <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>
      <!-- 構(gòu)建配置的唯一標(biāo)識符。即用于命令行激活三娩,也用于在繼承時合并具有相同標(biāo)識符的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>

Dependency Management -- 依賴管理

除了繼承某些頂級元素外庵芭,父元素還可以為子POM們傳遞依賴項配置值,其中一個父元素就是dependencyManagement雀监。

  • dependencyManagement被用于幫助POM管理所有孩子節(jié)點的依賴信息双吆。
    例子:假設(shè)父工程my-project使用dependencyManagement定義了一個依賴"junit:junit:4.12",然后繼承了該工程的一個pom只設(shè)置了 groupId=junit 和 artifactId=junit 那么Maven會通過其父pom的version將其補全会前。
  • 這種方式的優(yōu)點:你可以在一個核心位置設(shè)置依賴信息好乐,然后將其傳播給繼承了它的pom。
  • 注意:從傳遞依賴合并而來的artifact的version和scope也由依賴項管理部分中的版本規(guī)范控制瓦宜,這可能會導(dǎo)致意想不到的后果蔚万。例子:你的項目有兩個依賴項 dep1 和 dep2,同時dep2也依賴dep1临庇,并且需要一個特定的版本來運行反璃。如果此時你使用dependencyManagement來指定一個較舊的版本,那么dep2將被迫使用舊版本運行假夺,就會失敗版扩。因此你必須檢查整個依賴樹(mvn dependency:tree)以避免此類問題。

Aggregation(Multi-Module)-- 聚合

??????一個具有modules的項目被稱為多模塊或聚合項目侄泽。modules是POM列出的項目礁芦,并作為一個組執(zhí)行。packaging為pom的項目可以聚合構(gòu)建modules中列出的項目悼尾,這些模塊是這些項目的目錄或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>
 
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>my-parent</artifactId>
  <version>2.0</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>my-project</module>
    <module>another-project</module>
    <module>third-project/pom-example.xml</module>
  </modules>
</project>

??????在modules列表中不必考慮模塊間的依賴關(guān)系,modules中的列表順序也是不重要的闺魏。Maven會對這些模塊進行拓展排序未状,這樣dependency總是在依賴它的modules之前構(gòu)建。

Inheritance(繼承) VS Aggregation(聚合)
??????聚合和繼承都可以通過一個單一的高層次的POM來動態(tài)的控制build析桥。你經(jīng)乘静荩可以看到一個項目既有parents又有繼承艰垂。例如,整個Maven核心通過一個基礎(chǔ)POM org.apache.maven:maven 運行埋虹,所以在build這個Maven工程的時候可以執(zhí)行一個簡單的命令:mvn compile猜憎。但是聚合項目和父項目都是POM工程,他們不是一個也不一樣搔课,千萬不要混淆胰柑。一個POM可以被繼承但不一定具有任何聚合的modules。相反的爬泥,一個POM工程也可以聚合不從它繼承的項目柬讨。

Properties

??????properties是了解POM基礎(chǔ)知識的最后一個必選項。Maven properties和Ant中的properties類似袍啡,是占位符的值踩官。它們的值可以通過使用${X}符號在POM中的任何地方訪問,其中X是屬性境输÷衾穑或者它們可以作為默認(rèn)值被插件使用,例如:

<project>
  ...
  <properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>
  ...
</project>

它們有五種不同的風(fēng)格:

  1. env.X
    在變量前面加上"env."將返回shell的環(huán)境變量畴嘶。例如${env.PATH}包含PATH環(huán)境變量。注意:雖然環(huán)境變量本身在Windows上是大小寫不敏感的集晚,但是對屬性的查找是大小寫敏感的窗悯。換句話說,當(dāng)Windows shell為%PATH%和%Path%返回相同的值時偷拔,Maven會區(qū)分${env.PATH}和$ {env.Path}蒋院。為了保證可靠性,環(huán)境變量的名稱被規(guī)范化為全大寫莲绰。
  2. project.x
    POM中的點(.)標(biāo)記路徑將包含相應(yīng)元素的值欺旧。
    例如:<project><version>1.0</version></project>與變量${project.version}相通。
  3. setting.x
    setting.xml中的點(.)標(biāo)記路徑將包含相應(yīng)元素的值蛤签。
    例如:<settings><offline>false</offline></settings>與變量${settings.offline}相通辞友。
  4. Java System Properties(Java系統(tǒng)屬性):
    通過java.lang.System.getProperties()獲取到的所有屬性都可以作為POM屬性使用,例如:${java.home}
  5. x
    POM文件中的properties屬性設(shè)置的值震肮。
    例如:<properties><someVar>value</someVar></properties>與變量${someVar}相通称龙。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戳晌,隨后出現(xiàn)的幾起案子鲫尊,更是在濱河造成了極大的恐慌,老刑警劉巖沦偎,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疫向,死亡現(xiàn)場離奇詭異咳蔚,居然都是意外死亡,警方通過查閱死者的電腦和手機搔驼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門谈火,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匙奴,你說我怎么就攤上這事堆巧。” “怎么了泼菌?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵谍肤,是天一觀的道長。 經(jīng)常有香客問我哗伯,道長荒揣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任焊刹,我火速辦了婚禮系任,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虐块。我一直安慰自己俩滥,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布贺奠。 她就那樣靜靜地躺著霜旧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪儡率。 梳的紋絲不亂的頭發(fā)上挂据,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機與錄音儿普,去河邊找鬼崎逃。 笑死,一個胖子當(dāng)著我的面吹牛眉孩,可吹牛的內(nèi)容都是我干的个绍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浪汪,長吁一口氣:“原來是場噩夢啊……” “哼障贸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吟宦,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤篮洁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后殃姓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袁波,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡瓦阐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了篷牌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睡蟋。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖枷颊,靈堂內(nèi)的尸體忽然破棺而出戳杀,到底是詐尸還是另有隱情,我是刑警寧澤夭苗,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站题造,受9級特大地震影響傍菇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜界赔,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一丢习、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淮悼,春花似錦咐低、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞧挤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間儡湾,已是汗流浹背特恬。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徐钠,地道東北人癌刽。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像尝丐,于是被迫代替她去往敵國和親显拜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354