IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    《Maven官方文档》POM文件

    liguangsheng发表于 2016-04-20 17:28:21
    love 0

    原文网址:The POM

    什么是POM?

    POM(project object modal)包含了工程信息和工程的配置细节,Maven使用POM文件来构建工程。POM文件包含了工程中的大部分默认值。举个例子,target是默认的构建目录,src/main/java是默认的源码目录,src/test/java是默认的测试源码目录,等等。

    Maven2中的pom.xml就是Maven1中的project.xml。相比于在maven.xml中包含可执行的goal,现在goals和plugins都可以在pom.xml中配置。当执行一个task或者goal时,Maven会在当前目录下寻找并读取pom.xml来获取配置信息,然后执行goal。

    能在pom.xml中声明的配置包括工程依赖(project dependencies),插件(plugins),可执行的目标(goals),构建配置(build profiles)等等。其他信息,比如工程版本,描述,开发者,邮件列表等等也可以在pox.xml中声明。

    Super POM

    Super POM是Maven的默认POM文件,除非你显示的声明继承关系,否则所有的POM文件都是在Super POM的基础上的扩展,也就是说,Super POM中的的配置会被你的工程中创建的pom.xml继承。Maven 2.0.x中的Super POM代码如下:

    <project>
      <modelVersion>4.0.0</modelVersion>
      <name>Maven Default Project</name>
     
      <repositories>
        <repository>
          <id>central</id>
          <name>Maven Repository Switchboard</name>
          <layout>default</layout>
          <url>http://repo1.maven.org/maven2</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
     
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <name>Maven Plugin Repository</name>
          <url>http://repo1.maven.org/maven2</url>
          <layout>default</layout>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <releases>
            <updatePolicy>never</updatePolicy>
          </releases>
        </pluginRepository>
      </pluginRepositories>
     
      <build>
        <directory>target</directory>
        <outputDirectory>target/classes</outputDirectory>
        <finalName>${artifactId}-${version}</finalName>
        <testOutputDirectory>target/test-classes</testOutputDirectory>
        <sourceDirectory>src/main/java</sourceDirectory>
        <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
        <testSourceDirectory>src/test/java</testSourceDirectory>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
          </resource>
        </resources>
        <testResources>
          <testResource>
            <directory>src/test/resources</directory>
          </testResource>
        </testResources>
      </build>
     
      <reporting>
        <outputDirectory>target/site</outputDirectory>
      </reporting>
     
      <profiles>
        <profile>
          <id>release-profile</id>
     
          <activation>
            <property>
              <name>performRelease</name>
            </property>
          </activation>
     
          <build>
            <plugins>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
     
                <executions>
                  <execution>
                    <id>attach-sources</id>
                    <goals>
                      <goal>jar</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
     
                <executions>
                  <execution>
                    <id>attach-javadocs</id>
                    <goals>
                      <goal>jar</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
     
                <configuration>
                  <updateReleaseInfo>true</updateReleaseInfo>
                </configuration>
              </plugin>
            </plugins>
          </build>
        </profile>
      </profiles>
     
    </project>
    

    下面是Maven 2.1.x的Super POM:

    <project>
      <modelVersion>4.0.0</modelVersion>
      <name>Maven Default Project</name>
     
      <repositories>
        <repository>
          <id>central</id>
          <name>Maven Repository Switchboard</name>
          <layout>default</layout>
          <url>http://repo1.maven.org/maven2</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
     
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <name>Maven Plugin Repository</name>
          <url>http://repo1.maven.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>
        <!-- TODO: MNG-3731 maven-plugin-tools-api < 2.4.4 expect this to be relative... -->
        <scriptSourceDirectory>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>
           <plugins>
             <plugin>
               <artifactId>maven-antrun-plugin</artifactId>
               <version>1.3</version>
             </plugin>       
             <plugin>
               <artifactId>maven-assembly-plugin</artifactId>
               <version>2.2-beta-2</version>
             </plugin>         
             <plugin>
               <artifactId>maven-clean-plugin</artifactId>
               <version>2.2</version>
             </plugin>
             <plugin>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>2.0.2</version>
             </plugin>
             <plugin>
               <artifactId>maven-dependency-plugin</artifactId>
               <version>2.0</version>
             </plugin>
             <plugin>
               <artifactId>maven-deploy-plugin</artifactId>
               <version>2.4</version>
             </plugin>
             <plugin>
               <artifactId>maven-ear-plugin</artifactId>
               <version>2.3.1</version>
             </plugin>
             <plugin>
               <artifactId>maven-ejb-plugin</artifactId>
               <version>2.1</version>
             </plugin>
             <plugin>
               <artifactId>maven-install-plugin</artifactId>
               <version>2.2</version>
             </plugin>
             <plugin>
               <artifactId>maven-jar-plugin</artifactId>
               <version>2.2</version>
             </plugin>
             <plugin>
               <artifactId>maven-javadoc-plugin</artifactId>
               <version>2.5</version>
             </plugin>
             <plugin>
               <artifactId>maven-plugin-plugin</artifactId>
               <version>2.4.3</version>
             </plugin>
             <plugin>
               <artifactId>maven-rar-plugin</artifactId>
               <version>2.2</version>
             </plugin>        
             <plugin>                
               <artifactId>maven-release-plugin</artifactId>
               <version>2.0-beta-8</version>
             </plugin>
             <plugin>                
               <artifactId>maven-resources-plugin</artifactId>
               <version>2.3</version>
             </plugin>
             <plugin>
               <artifactId>maven-site-plugin</artifactId>
               <version>2.0-beta-7</version>
             </plugin>
             <plugin>
               <artifactId>maven-source-plugin</artifactId>
               <version>2.0.4</version>
             </plugin>         
             <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4.3</version>
             </plugin>
             <plugin>
               <artifactId>maven-war-plugin</artifactId>
               <version>2.1-alpha-2</version>
             </plugin>
           </plugins>
         </pluginManagement>
      </build>
     
      <reporting>
        <outputDirectory>${project.build.directory}/site</outputDirectory>
      </reporting>
      <profiles>
        <profile>
          <id>release-profile</id>
     
          <activation>
            <property>
              <name>performRelease</name>
              <value>true</value>
            </property>
          </activation>
     
          <build>
            <plugins>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                  <execution>
                    <id>attach-sources</id>
                    <goals>
                      <goal>jar</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <executions>
                  <execution>
                    <id>attach-javadocs</id>
                    <goals>
                      <goal>jar</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                  <updateReleaseInfo>true</updateReleaseInfo>
                </configuration>
              </plugin>
            </plugins>
          </build>
        </profile>
      </profiles>
     
    </project>
    

    最小化POM

    一个最小化的POM文件的要求如下:

    • project 标签作为顶层标签
    • modelVersion – 应该设为4.0.0
    • groupId – 工程开发组的唯一id
    • artifactId – 工件(artifact)或工程(projrct)的唯一id
    • version – 版本号

    这里是一个最小化POM的例子:

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

    在POM文件中需要声明 groupId ,  artifactId 和 version 。这三个值以<groupId>:<artifactId>:<version>的形式声明,它们组成了工程的完整名称。比如上面的例子,完整名称为”com.mycompany.app:my-app1″。

    如第一节所说,如果配置细节没有显示的设置,Maven将会使用继承自Super POM默认配置。其中一个默认值就是包的类型(packaging type),每个Maven工程都有一个包类型,如果没有在POM中设置,则默认为”jar”。

    前面的Minimal POM中,其中 repositories 这个值没有设置,如果你使用minimal POM来构建你的工程,它将使用继承Super POM中的 repositories 值(http://repo.maven.apache.org/maven2),当Maven在POM中找到依赖,它就会去这个地址下载依赖包。

    工程继承

    POM中可配置的元素如下:

    • 依赖 (dependencies)
    • 开发者和贡献者 (developers and contributors)
    • 插件列表,包括报告 (plugin lists, including reports)
    • 相应id的插件执行 (plugin executions with matching ids)
    • 插件配置 (plugin configuration)
    • 资源 (resources)

    Super POM就是一个工程继承的例子。你也可以通过在POM中指定parent element来引入你自己的POM作为基础。就像下面的例子:

    Example 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.xml 是com.mycompany.app:my-module:1 的POM文件,而 pom.xml 是com.mycompany.app:my-app:1的POM文件。

    解决方案

    现在,如果我们将com.mycompany.app:my-app:1指定为com.mycompany.app:my-module:1的父工件(parent artifact),我们需要修改com.mycompany.app:my-module:1的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>
    

    注意,我们需要添加一个parent结点,这个结点允许我们指定当前POM的父POM。通过指定父POM的完整名称(即groupId,artifactId,version这三个标签),我们的模块(module)就能够继承父POM中的属性了。

    另外,如果我们希望groupId和模块的version和他们的parents相同,你可以移除当前模块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>
    

    这样做可以让当前模块集成父POM的groupid和version。

    Example 2

    情景

    在父工程已经安装在本地仓库或指定目录结构(父POM是模块POM的上一级目录)中时,这样做是可以得。

    但是如果父工程没有安装或者是像这样的目录机构呢?

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

    解决方案

    为了修正这个目录结构,我们将在parent结点中添加<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到其父POM的相对路径。

    工程聚合

    工程聚合和工程继承很相似,但不是从子模块指定父POM,而是从父POM指定子模块。这样做的话,父工程就知道子模块的存在了,而且如果Maven命令从父工程调用,在子模块中也能顺利执行。工程聚合要求如下做法:

    • 将父POM的packageing属性设为”pom”
    • 在父POM中指定模块的目录(子POM)

    Example 3

    情景

    还是上次的POM和目录结构

    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>

    directory structure

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

    解决方案

    如果我们准备将my-module聚合进my-app中,我们只需要修改my-app。

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

    在修改后的POM中,增加了packaging部分和模块部分,packaging的值设为”pom”,模块部分增加了<module>my-module</module>。<module>的值是com.mycompany.app:my-app:1到com.mycompany.app:my-module:1的POM的相对路径(练习中,我们用模块的artifactId作为目录名称)。

    现在,当Maven命令在com.mycompany.app:my-app:1中执行时,同样的明明也会在com.mycompany.app:my-module:1中执行。此外,有些命令(goals soecifically)以不同的方式处理工程聚合的情况。

    Example 4

    情景

    如果我们将目录结构改成这样

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

    父POM又该如何指定子模块呢?

    解决方案

    答案是 – 跟Example 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工程继承这个父工程,这些配置就能在所有的工程中通用了。

    如果你有一组工程一起构建和运行,你可以创建一个父工程,并在父工程中声明这些工程为它的模块,这样做,你只要构建父工程,子工程也会随之构建。

    当然,你可以同时做工程继承和工程聚合。这意味着,你可以为你的所有模块指定一个父工程,同时,父工程中可以指定其余的Maven工程为它的子模块。你只需要应用这三条规则:

    • 在所有子POM中指定它们的父POM。
    • 将父POM的packaging元素的值设为”pom”。
    • 在父POM中指定子模块(子POM)的目录。

    Example 5

    情景

    还是上次的POM,

    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

    解决方案

    同时做工程继承和工程聚合,你只要应用三条法则。

    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>

    注意:配置继承的策略与POM继承的策略相同

    工程改写和变量

    Maven鼓励的做法是不要做重复的工作(don’t repeat yourself)。但总有在不同的地方使用相同属性的情况。为了确保属性值指定一次,Maven允许你在POM使用你自己的变量或者预先定义的变量。

    举个例子,为了使用project.version这个变量,你可以这样引用:

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

    要注意的是这些变量在继承之后才会被处理。这意味着如果一个父工程使用了一个变量,它们在子工程中的定义与在父工程中的定义会不一样,是最后使用的那个。

    可用的变量

    工程模型变量

    一个Model的任何字段都是一个单独的可以做为变量引用的值元素。例如,${project.groupId}, ${project.version},${project.build.sourceDirectory} 等等。参考POM reference 列举的全部属性。这些变量都用”project”前缀来引用。你可以看看pom references. 作为前缀,或者完全省略前缀 – 这些形式现在已经废弃不再使用了。

    特殊变量

    project.basedir 当前工程所在的目录
    project.baseUri 当前工程所在的目录,表示为一个URI,Maven 2.1.0之后
    maven.build.timestamp 时间戳,表示开始构建的时间,Maven 2.1.0-M1之后

    构建时间戳的格式可以在maven.build.timestamp.format属性中自定义,示例如下:

    <project>
      ...
      <properties>
        <maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
      </properties>
      ...
    </project>

    格式化模式必须遵守API文档中给出的规则。如果这个属性不存在,默认值就是示例中给出的值

    属性

    你同样可以将任何在工程中定义的属性作为变量引用,看看下面的例子:

    <project>
      ...
      <properties>
        <mavenVersion>2.1</mavenVersion>
      </properties>
      <dependencies>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-artifact</artifactId>
          <version>${mavenVersion}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-project</artifactId>
          <version>${mavenVersion}</version>
        </dependency>
      </dependencies>
      ...
    </project>
    

    原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《Maven官方文档》POM文件




沪ICP备19023445号-2号
友情链接