【Maven】【翻譯】2、POM.xml文件

一、什麼是POM?

POM是Project Object Model的縮寫,是Maven工作的基礎單元;POM.xml是一個包含關於Maven項目信息和配置詳情的XML文件,是用來構建(build)項目的;它包含大多數項目的默認值;例如,構建項目的【target】文件夾;例如,資源文件夾——【src/main/java】;例如測試資源文件夾——【src/test/java】等等;當執行一個任務或目標,Maven會在當前文件夾內找POM文件。然後讀取POM裏的信息,獲取需要的配置信息,然後執行目標;
一些POM裏的特殊配置是項目的依賴(Project Dependencies);這裏的依賴指的是項目依賴的jar包;還有一些事插件或可執行的目標,構建配置等;其他的信息例如項目版本,描述,開發者,郵件列表等都可以被特別定義;

二、超級POM

超級POM是Maven默認的POM,所有的POM文件們都繼承了這個超級POM,除非明確定義了不繼承;超級POM文件被你創建的其他POM文件們繼承,目前最新的超級POM文件是3.5.4;(你可以理解爲所有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>

三、最簡單的POM

最簡單的POM文件要求有一下5個部分:

  1. 項目根目錄;
  2. 模塊版本-必須被設置成4.0.0;
  3. 組別ID-項目的組別的ID;
  4. 產品ID-項目產品的ID;
  5. 版本-在特定組別下的項目產品的版本;

下面是一個例子

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

一個POM文件會要求配置你的groupId,artifactId和版本號;這3個值可以完整的定義一個產品;以<groupId>:<artifactId>:<version>的形式;按照上面的例子,上面項目完整的產品名是:

com.mycompany.app:my-app:1

同樣的,第一節提到的,如果沒有明確定義配置信息,Maven會使用默認值。其中一種默認值是打包類型(packaging type);每個Maven 項目都有一個打包類型;如果POM裏沒有明確定義,那麼,默認的打包類型會是jar包;

此外,你可以看到,最簡單的POM文件裏,倉庫(repositories)是沒有明確配置的。如果你使用最簡單的POM文件來構建項目,他會繼承超級POM的倉庫配置;因此,當Maven看到最簡單POM文件裏的依賴,他會直接去中央倉庫去下載(http://repo.maven.apache.org/maven2),這是所有POM文件的超級POM配置倉庫;

四、項目繼承

POM文件裏元素的會被合併如下:

  1. 依賴jar包
  2. 開發者和貢獻者
  3. 插件列表(包括報告)
  4. 匹配到id的插件;
  5. 插件配置
  6. 資源

超級POM文件是一個項目繼承的經典例子,但是,如果你想通過特定的POM中父類元素引入你自己的父類POM文件,建議看看以下案例演示:

4.1、案例一
舉例如下,讓我們複用前面的產品,com.mycompany.app:my-app:1,並且讓我們引入一個其他的產品:com.mycompany.app:my-module:1

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

讓我們特別定義文件目錄結構如下:

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

注意:my-module/pom.xmlcom.mycompany.app:my-module:1 產品的POM文件;
pom.xmlcom.mycompany.app:my-app:1產品的POM文件;

解決方案
現在,如果我們把com.mycompany.app:my-app:1 設爲com.mycompany.app:my-module:1 的父類項目;那麼,我們必須修改com.mycompany.app:my-module:1的POM文件如下:(即,我們再子類的POM文件裏修改,添加父類的信息)

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

注意,我們添加了一個標籤組節,這個組節允許我們在POM文件裏特別定義產品的父類信息;我們通過定義其父類POM的【全限定產品名】(fully qualified artifact name);我們的模塊就可以繼承其父類POM了;

除此之外,如果我們想讓我們模塊的groupID或version和其父類一樣,我們可以移除子類模塊POM文件中的groupId或version;

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

4.2、案例二
然而,上述案例一的那種情況,必須是父項目已經在我們本地倉庫安裝(installed)或者被特別定義了結構pom.xml 父pom.xml是一個比你當前模塊的pom.xml高級的文件夾;
但是,如果父項目沒有被安裝或者文件夾結構是如下的例子:

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

解決方案:
添加文件夾結構地址(或任意其他目錄地址),我們可以添加關聯路徑<relativePath> 原來到父組節裏

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

作爲名字的建議,模塊的相對路徑的pom.xml是父pom.xml

五、項目聚合

項目的聚類類似於項目的繼承,但是不是在模塊的父pom文件,而是在父POM裏;通過這樣的操作,父項目可以知道他的子模塊,並且,如果Mavne命令是在父項目裏調用的,Maven命令可以在父模塊中執行;爲了做模塊聚合,你必須做如下操作:


 1. 修改父POMs打包的值爲pom(而不是jar)
 2. 特別定義父類的POM中子模塊的目錄

5.1、案例三
下面給定了一個原始的產品的POMs和目錄結構

com.mycompany.app:my-app:1's POM


的POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

com.mycompany.app:my-module:1's POM

的POM文件

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

目錄結構

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

解決方案
如果我們想將my-module 模塊聚合到 my-app 模塊,我們需要緊緊修改my-app 模塊的POM:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>my-module</module>
  </modules>
</project>

在修訂後的com.mycompany.app:my-app:1 模塊,打包的組節和模塊的組節被添加進去了;爲了打包,他的值被修改爲了“pom”,並且模塊的組節,我們有元素:<module>my-module</module> 模塊的值是com.mycompany.app:my-app:1 相對 com.mycompany.app:my-module:1's POM 的相對路徑;(我們特別用了模塊的產品的模塊目錄名);

現在,無論Maven命令處理 com.mycompany.app:my-app:1 ,相同的maven命令會同時在 com.mycompany.app:my-module:1 裏執行;此外,一些命令(目標特別定義)的會被項目特殊處理;

5.2、案例四
但是,如果我們按照下面的來修改目錄呢?

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

父類的POM會不會被模塊特別定義?

解決方案:
答案?和案例3一樣,通過特別定義模塊的相對路徑:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>../my-module</module>
  </modules>
</project>

即可;

  • [ ]

六、項目繼承和項目聚合的比較

如果你有好幾個Maven工程,並且他們都有相似的配置,你可以通過添加父類項目和相似的配置文件來重構項目;所有你要做的就是讓你的Maven工程繼承其父類項目,並且配置必須與其一致;

並且,如果你有一個項目組,你要構建或者同時處理,你可以創建一個父工程,並且讓父工程來定義它的子類;這樣,你緊緊需要構建父項目,其他的子項目就會自動執行,不需要你操心了;

但是,同樣的,你如果既有項目繼承又有項目依賴;注意,你可以特定一個父項目,同時,定義這個父項目的子項目;你必須遵循下面3條規則:


 1. 在父POM定義其所有的子項目POM;
 2. 修改父項目的POMs的打包方式爲pom
 3. 特別定義父POM的目錄給子項目;

6.1、案例5
給定了如下原始的POMs的產品

com.mycompany.app:my-app:1’s POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

com.mycompany.app:my-module:1’s POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

目錄結構如下:

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

解決方案
爲了兩個項目都繼承和聚合,你僅僅需要遵從上述3條內容;
com.mycompany.app:my-app:1’s POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>../my-module</module>
  </modules>
</project>

com.mycompany.app:my-module:1’s POM

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

注意:配置文件的繼承相同的繼承策略;

七、項目插值與變量

Maven鼓勵的一個經驗就是【不要重複】;然而,如果你需要使用在不同的地方多次使用相同的變量;爲了幫助變量是唯一定義的,Maven允許你在POM文件裏預定義自己的變量;

例如,爲了得到 project.version 變量,你可以定義如下:

 <version>${project.version}</version>

注意一個事實,變量在被繼承之後處理;這意味着,如果一份父項目要使用一個變量,如果這個變量定義在子項目中,而不是父項目中,則子項目中的變量將會被最終使用;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章