@Maven POM 详解

  • 前言
    • 什么是 POM
    • Quick Overview
  • POM 常用元素
  • pom.xml 完整注释
  • 参考

0 前言

什么是 POM?

就像 Make 的 MakeFile、Ant 的 build.xml 一样,Maven 项目的核心是 pom.xml。POM( Project Object Model,项目对象模型 ) 定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。

Quick Overview

一个完整的 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">
  <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>


tips:这里的 pom.xmlmodelVersion 为 4.0.

1 POM 常用元素

1.1 The Basics

1.1.1 Maven 坐标( Coordinate )

在 Maven 中坐标是构件的唯一标识,Maven 坐标的元素包括 groupIdartifactIdversionpackagingclassifier。上述5个元素中,groupIdartifactIdversion 是必须定义的,packaging 是可选的 ( 默认为 jar )。

  • groupId:组织标识,一般为:公司网址的反写+项目名
  • artifactId:项目名称,一般为:项目名-模块名
  • version:版本号
  • packaging:打包的方式,如:pom, jar, maven-plugin, ejb, war, ...
  • clissifier:用来帮助定义构件输出的一些附属构件。可参考此文

另外,关于 版本号 ,形式为0.0.1-SNAPSHOT

  • 第一个 0 表示大版本号,第二个 0 表示分支版本号,第三个 0 表示小版本号
  • SNAPSHOT -- 快照版本,ALPHA -- 内侧版本,BETA -- 公测版本,RELEASE -- 稳定版本,GA -- 正式发布

在我们开发自己的 maven 项目的时候,需要为其定义适当的坐标,如:

<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>
 
  <!-- 项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.seyvoue.demo生成的相对路径为:/com/seyvoue/demo--> 
  <groupId>com.seyvoue.demo</groupId>
  <!-- 构件的标识符,它和 groupId 一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的 artifactId 和 groupId;在某个特定的 groupId 下,artifactId也必须是唯一的。-->
  <artifactId>demo-maven</artifactId>
  <!-- 项目当前版本,格式为:主版本.次版本.增量版本-限定版本号-->
  <version>1.0.0-SNAPSHOT</version>
  <!-- 项目产生的构件类型,例如 jar、war、pom 等。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型-->
  <packaging>jar</packaging>
  
  ...
  
</project>

1.1.2 依赖: <dependencies>...</dependencies>

比如,我的项目 project-demo1 需要添加 junit 依赖:

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.0</version>
      <type>jar</type>
      <scope>test</scope>
      <optional>true</optional>
    </dependency>
    ...
</dependencies>


dependencies元素,包括以下子元素:

  • groupId, artifactId, version

这三个是必须的,以下的那些子元素根据实际情况添加。

  • scope

scope 元素为 maven dependency 下一个控制作用域的子元素,控制该依赖包在什么情况下会被加到 classpath 中。共 6 种 scope,包括:compileprovidedruntimetestsystemimport
( 具体可参考@POM Dependency Scope )

  • type

对于于 <packaging>...</packaging> ,即指定依赖包的后缀,默认为 jar

  • optional

如果当前仙姑是 projectA,projectA 需要依赖 projectB,而 projectB 的 optional 为 true,表示依赖可选,那么之后所有声明依赖 projectA 的项目如果也依赖 projectB,就必须手动声明。
比如,projectC 依赖 projectA 和 projectB,如果 projectC只声明了对 projectA 的依赖,那么 projectB 不会自动加入依赖,projectA 必须手动加入对 projectB 的依赖。
也就是说依赖传递被打断了。

  • exclusions

依赖传递:如果我们的项目引用了一个 Jar 包,而该 Jar 包又引用了其他 Jar 包,那么在默认情况下项目编译时,Maven 会把直接引用和间接引用的 Jar 包都下载到本地。

排除依赖:如果我们只想下载直接引用的 Jar包,
那么需要在 pom.xml 中做如下配置:(将需要排除的 Jar 包的坐标写在中)

<dependency>
 ...     
 <exclusions>
   <exclusion>
     <groupId>ch.qos.logback</groupId>
     <artifactId>logback-classic</artifactId>
   </exclusion>
 </exclusions>
 ...
</dependency>

依赖冲突:若项目中多个 Jar 同时引用了相同的 Jar 时,会产生依赖冲突,但 Maven 采用了两种避免冲突的策略,因此在 Maven 中是不存在依赖冲突的。

  • 短路优先
    本项目——>A.jar——>B.jar——>X.jar
    本项目——>C.jar——>X.jar
    若本项目引用了 A.jar,A.jar 又引用了 B.jar,B.jar 又引用了 X.jar,并且 C.jar 也引用了X.jar。
    在此时,Maven 只会引用引用路径最短的Jar。
  • 声明优先
    若引用路径长度相同时,在pom.xml中谁先被声明,就使用谁。

1.1.3 聚合: <modules>...</modules>

通过 <modules>...<modules> 元素可将多个模块聚合在同一个 project 下。

<project>  
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.seyvoue.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    ...
    
    <!--模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径-->
    <modules>  
        <module>account-email</module>  
        <module>account-persist</module>  
    </modules>
</project>  

1.1.4 继承: <parent>...</parent> 和 <dependencyManagement>...</dependencyManagement>

在聚合多个项目时,如果这些被聚合的项目中需要引入相同的 Jar,那么可以将这些 Jar 写入 父pom 中,各个子项目继承该pom即可。类似与 java 中的继承。
(具体可参考@Maven的聚合与继承)

如何实现继承? 示例如下:

  • 父 pom.xml:
  • <packaging>...</packaging> 必须配置为 pom
  • 将需要继承的 Jar 包的坐标放入<dependencyManagement>...</dependencyManagement> 内即可
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.seyvoue.demo</groupId>
  <artifactId> demo-maven </artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>
 
  ...
  <properties>
     <spring.version>4.0.2.RELEASE</spring.version>
     <junit.versoin>4.7</junit.version>
     ...
  </properties>
  
  <!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact 
  ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。-->
  <dependencyManagement>
    <dependencies>
      <dependency>
            <groupId>com.github.brevy</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.2</version>
      </dependency>
      ...
    </dependencies>
  </dependencyManagement>
  ...
  
</project> 

  • 子 pom.xml:

<parent>...</parent> 标签内添加 父pom.xml 的坐标

<project>  
    <modelVersion>4.0.0</modelVersion> 
    ... 
    <parent>  
        <groupId>com.seyvoue.demo</groupId>  
        <artifactId> demo-maven </artifactId>  
        <version>1.0.0-SNAPSHOT</version>
        <!-- 父pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../
        pom.xml。Maven首先在构建当前项目的地方寻找父pom.xml,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom。-->
        <relativePath>...</relativePath>  
    </parent>
    
    <!-- 子 POM 若引用父 POM 在 dependencyManagement 中定义过的依赖,则只需填写 groupId 和 artifactid,其它的信息则会从父 POM 中继承 -->
    <dependencies>
        <dependency>
             <groupId>com.github.brevy</groupId>
             <artifactId>shiro-spring</artifactId>
        </dependency>
        ...
    </dependencies>
    
    ...


</project>  

  • Maven 可继承的 POM 元素:
groupId :项目组 ID ,项目坐标的核心元素;  
version :项目版本,项目坐标的核心元素;  
description :项目的描述信息;  
organization :项目的组织信息;  
inceptionYear :项目的创始年份;  
url :项目的 url 地址  
develoers :项目的开发者信息;  
contributors :项目的贡献者信息;  
distributionManagerment :项目的部署信息;  
issueManagement :缺陷跟踪系统信息;  
ciManagement :项目的持续继承信息;  
scm :项目的版本控制信息;  
mailingListserv :项目的邮件列表信息;  
properties :自定义的 Maven 属性;  
dependencies :项目的依赖配置;  
dependencyManagement :醒目的依赖管理配置;  
repositories :项目的仓库配置;  
build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;  
reporting :包括项目的报告输出目录配置、报告插件配置等。  

1.1.5 属性:<properties>...</properties> 和 &{}

Maven 的 properties 加载顺序:

  • <build><filters> 中的配置
  • pom.xml 中的 <properties>
  • mvn -Dproperty=value 中定义的 property
    相同 key 的 property,以最后一个文件中的配置为最终配置。
<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>

通过 properties元素用户可以定义一个或多个 maven 属性,然后在 maven 的其他地方使用 ${属性名称} 的方式引用该属性,这种做法的意义在于消除重复和统一管理。比如,需要在多个地方重复声明同样的 SpringFramework 版本,现在只需要在一个地方声明就可以。Maven 共有6种属性(根据引用的来源不同):内置属性、POM 属性、自定义属性、Settings 属性、环境变量属性等,引用方式是类似的,下面介绍其中的集中

  • 内置属性

两个常用内置属性:

  • ${basedir} 表示项目根目录
  • ${version} 表示项目版本
  • POM 属性

用户可以使用该类属性引用 pom.xml 中对应元素的值,如 ${project.artifactId} 就对应了 <project><artifactId></artifactId></project> 中的值。常用的 POM 属性包括:

  • ${project.build.sourceDirectory} 表示项目的主源码目录,默认为 src/main/java
  • ${project.build.testDirectory} 表示项目的测试源码目录,默认为 src/test/java
  • ${project.build.directory} 表示项目项目构建输出目录,默认为 /target
  • ${project.outputDirectory} 表示项目主代码编译输出目录,默认为 /target/classes
  • ${project.build.filename} 表示项目打包输出文件的名称,默认为 ${project.artifactId}-${project.version}
  • 自定义属性

用户可以在 pom.xml 的<properties/> 元素下定义自己的 Maven 属性。如:

<project>
   ...
   <properties>
       <my.group>hello</my.group>
   </properties>
   ...
</project>

  • settings 属性

与 POM 属性同理。maven settings.xml 中定义的内容,可以通过 settings 前缀进行引用。

${settings.localRepository} 表示 maven 本地仓库的路径
${settings.offline} 表示构建系统是否在离线模式下工作

1.2 Build Settings

根据 POM 4.0.0 XSD,build 元素概念性的划分为两个部分:BaseBuild(包含 poject build 和 profile build 的公共部分,见下)和 poject 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  
                        http://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>  

1.2.1 <build>...</build>

1.2.1.1 The BaseBuild Element Set
Basic Elements
<build>  
    <defaultGoal>install</defaultGoal>  
    <directory>${basedir}/target</directory>  
    <finalName>${artifactId}-${version}</finalName>  
    <filters>  
        <filter>filters/filter1.properties</filter>  
    </filters>  
    ...  
</build>  

  • defaultGoal:执行build任务时,如果没有指定目标,将使用的默认值,如:在命令行中执行mvn,则相当于执行mvn install;
  • directory:build目标文件的存放目录,默认在 ${basedir}/target目录
  • finalName:build目标文件的文件名,默认情况下为${artifactId}-${version}
  • filter:定义*.properties文件,包含一个properties列表,该列表会应用的支持filter的resources中。也就是说,定义在filter的文件中的"name=value"值对会在build时代替 ${name} 值应用到 resources 中。Maven的默认filter文件夹是 ${basedir}/src/main/filters/
<Resources>...</Resources>

Maven 属性默认只有在 pom.xml 中才会被解析,对于放在 src/main/resources/ 目录下的文件,maven 是需要通过 maven-resources-plugin 插件帮忙处理的,它默认的行为是将项目资源文件复制到代码编译输出目录中,不过只要通过一些简单的 POM 配置,该插件就能解析资源文件中的 Maven 属性,即开启资源过滤。
resources(通常)不是代码,他们不被编译,但是被绑定在你的项目或者用于其它什么原因,例如代码生成。

<build>  
    ...  
    <resources>  
         <resource>  
            <targetPath>META-INF/plexus</targetPath>  
            <filtering>false</filtering>  
            <directory>${basedir}/src/main/plexus</directory>  
            <includes>  
                <include>configuration.xml</include>  
            </includes>  
            <excludes>  
                <exclude>**/*.properties</exclude>  
            </excludes>  
         </resource>  
    </resources>  
    <testResources>  
        ...  
    </testResources>  
    ...  
</build>  
  • resources:一个resource元素的列表,每一个都描述与项目关联的文件是什么和在哪里;
  • targetPath:指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF;
  • filtering:true/false,表示为这个resource,filter是否激活。
  • directory:定义resource所在的文件夹,默认为 ${basedir}/src/main/resources
  • includes:指定作为resource的文件的匹配模式,用 * 作为通配符;
  • excludes:指定哪些文件被忽略,如果一个文件同时符合 includesexcludes,则 excludes生效;
  • testResources:定义和 resource 类似,但只在 test 时使用,默认的 test resource文件夹路径是 ${basedir}/src/test/resourcestest resource 不被部署。
<plugins>...</plugins>

<plugins/> 给出构建过程中所用到的插件,以及可以在这个元素下对插件进行配置。

<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>
       <excution>
         <id>echodir</id>
         <goals>
           <goal>run</goal>
         </goals>
         <phase>verify</phase>
         <inherited>false</inherited>
         <configuration>
           <task>
             <echo>Build Dir: ${project.build.directory}</echo>
           </task>
         </configuration>
       </excution>
     </executions>  
   </plugin>  
 </plugins>  
</build>  

  • extensions:是否加载该插件的扩展,默认false
  • inherited:该插件的 configuration 中的配置是否可以被(继承该POM的其他Maven项目)继承,默认true
  • configuration:该插件所需要的特殊配置,在父子项目之间可以覆盖或合并
  • dependencies:该插件所特有的依赖类库
  • executions:plugin 可以有多个目标,每一个目标都可以有一个分开的配置,甚至可以绑定一个 plugin 的目标到一个不同的阶段。executions 配置一个 plugin 的目标的 execution。一个 execution 有如下设置:
    • id,唯一标识
    • goals,要执行的插件的 goal(可以有多个),如 <goal>run</goal>
    • phase,目标执行的阶段,具体值看Maven的生命周期列表
    • inherited,该 execution 是否可被子项目继承
    • configuration,该 execution 的其他配置参数
<pluginManagement>...<pluginManagement>

<build> 中,<pluginManagement><plugins> 并列,两者之间的关系类似于 <dependencyManagement><dependencies> 之间的关系。<pluginManagement> 中也配置 <plugin>,其配置参数与 <plugins> 中的 <plugin> 完全一致。只是,<pluginManagement> 往往出现在父项目中,其中配置的 <plugin> 往往通用于子项目。子项目中只要在 <plugins> 中以 <plugin> 声明该插件,该插件的具体配置参数则继承自父项目中 <pluginManagement> 对该插件的配置,从而避免在子项目中进行重复配置。

1.2.2 <reporting>...</reporting>

<reporting> 中的配置作用于 Maven 的 site 阶段( 见 Maven 生命周期),用于生成报表。<reporting> 中也可以配置插件 <plugins>,并通过一个 <plugin> 的 <reportSet>为该插件配置参数。注意,对于同时出现在 <build> 和 <reporting> 中的插件,<reporting> 中对该插件的配置也能够在构建过程中生效,即该插件的配置是<build>和<reporting>中的配置的合并。

1.3 Environment Settings

<SCM>...</SCM>

Maven中为我们集成了软件配置管理的(SCM:Software Configuration Management)功能,他可以支持我们常用SVN、CVS等,共支持18个命令:

scm:branch - branch the project(创建项目的分支)
scm:validate - validate the scm information in the pom(校验SCM的配置信息)
scm:add - command to add file(增加一个文件)
scm:unedit - command to stop editing the working copy(停止编辑当前COPY)
scm:export - command to get a fresh exported copy(拉一个全新的分支)
scm:bootstrap - command to checkout and build a project(checkout并编译工程)
scm:changelog - command to show the source code revisions(显示源码版本)
scm:list - command for get the list of project files(列出工程的文件)
scm:checkin - command for commiting changes(提交变更)
scm:checkout - command for getting the source code(获取源码)
scm:status - command for showing the scm status of the working copy(获取本地项目的状态)
scm:update - command for updating the working copy with the latest changes(从服务器获取最新的版本)
scm:diff - command for showing the difference of the working copy with the remote one(比较本地与远程服务器的差异)
scm:update-subprojects - command for updating all projects in a multi project build(更新子项目)
scm:edit - command for starting edit on the working copy(编辑)
scm:tag - command for tagging a certain revision(打标签)
 

tips:而其中的 mvn scm:checkin, mvn scm:update是其中比较常用的命令。

比如,对 git 的配置如下:

<project>

    ...

    <scm>     
        <!--SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和列表。该连接只读。-->     
        <connection>     
            scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)      
        </connection>     
        <!--给开发者使用的,类似connection元素。即该连接不仅仅只读-->    
        <developerConnection>     
            scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk      
        </developerConnection>    
        <!--当前代码的标签,在开发阶段默认为HEAD-->    
        <tag/>           
        <!--指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。-->     
        <url>http://svn.baidu.com/banseon</url>     
    </scm> 
    
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <version>2.5.3</version>
        <configuration>
            <tagBase>${git.conn}</tagBase>
            <branchBase>${git.conn}</branchBase>
            <username>${git.username}</username>
            <password>${git.password}</password>
        </configuration>
    </plugin>
    
    ...

</project>

<distributionManagement>...</distributionManagement>

maven 中的仓库分为两种,snapshot 快照仓库和 release 发布仓库。snapshot 快照仓库用于保存开发过程中的不稳定版本,release 正式仓库则是用来保存稳定的发行版本。定义一个组件/模块为快照版本,只需要在 pom 文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写),在distributionManagement段中配置的是snapshot快照库和release发布库的地>址。

<project>
  <!--项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。--> 
  <distributionManagement>
          <!--部署项目产生的构件到远程仓库需要的信息--> 
          <repository>
              <id>${distribution.releases.id}</id>
              <url>${distribution.releases.url}</url>
          </repository>
          <snapshotRepository>
              <id>${distribution.snapshots.id}</id>
              <url>${distribution.snapshots.url}</url>
          </snapshotRepository>
  </distributionManagement>
</project>

<profiles>...</profiles>

不同环境的构建很可能是不同的,典型的情况就是数据库的配置。要想使得一个构建不做任何修改就能在任何环境下运行,往往是不可能的,为了能让构建在各个环境下方便地移植,Maven 引入了 profile 的概念,profile 能够在构建的时候选择性的激活 pom.xml 中的元素。用户可以使用很多方式激活 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">
 ...
 <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>

2. 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">
  <modelVersion>4.0.0</modelVersion>
 
  <!-- 项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.seyvoue.demo生成的相对路径为:/com/seyvoue/demo--> 
  <groupId>com.seyvoue.demo</groupId>
  <!-- 构件的标识符,它和 groupId 一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的 artifactId 和 groupId;在某个特定的 groupId 下,artifactId也必须是唯一的。-->
  <artifactId>demo-maven</artifactId>
  <!-- 项目当前版本,格式为:主版本.次版本.增量版本-限定版本号-->
  <version>1.0.0-SNAPSHOT</version>
  <!-- 项目产生的构件类型,例如 jar、war、pom 等。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型-->
  <packaging>jar</packaging>
  <!-- 项目的名称,Maven产生的文档用-->     
  <name>project-demo</name>
  <!-- 项目主页的URL,Maven产生的文档用-->
  <url>http://demo.seyvoue.com</url>
  <!-- 项目的详细描述, Maven 产生的文档用。当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的索引页文件,而不是调整这里的文档。-->
  <description>A demo of maven project to study maven.</description>
  


  <parent>    
    <!--被继承的父项目的构件标识符-->    
    <artifactId/>    
    <!--被继承的父项目的全球唯一标识符-->    
    <groupId/>    
    <!--被继承的父项目的版本-->    
    <version/>    
    <!-- 父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。Maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom。-->    
    <relativePath/>    
 </parent>


  <!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。-->    
  <dependencyManagement>    
    <dependencies>    
      <!--参见dependencies/dependency元素-->    
      <dependency>    
      ...    
      </dependency>    
    </dependencies>    
 </dependencyManagement>



  <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。-->     
  <dependencies>     
    <dependency>    
      <!--依赖的group ID-->    
      <groupId>org.apache.maven</groupId>     
      <!--依赖的artifact ID-->    
      <artifactId>maven-artifact</artifactId>     
      <!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。-->    
      <version>3.8.1</version>     
      <!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应,   这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为 true,就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。-->    
      <type>jar</type>    
      <!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成 JAR,一个使用Java    4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件。-->    
      <classifier></classifier>    
      <!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。    
        - compile :默认范围,用于编译      
        - provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath      
        - runtime: 在执行时需要使用      
        - test:    用于test任务时使用      
        - system: 需要外在提供相应的元素。通过systemPath来取得      
        - systemPath: 仅用于范围为system。提供相应的路径      
        - optional:   当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用-->     
      <scope>test</scope>       
      <!--仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例{java.  home}。-->    
      <systemPath></systemPath>     
      <!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题-->    
      <exclusions>    
        <exclusion>     
          <artifactId>spring-core</artifactId>     
          <groupId>org.springframework</groupId>     
        </exclusion>     
      </exclusions>       
      <!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。-->     
      <optional>true</optional>    
    </dependency>
    ...    
  </dependencies>




  <!--模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径-->
  <modules>  
      <module>account-email</module>  
      <module>account-persist</module> 
      ... 
  </modules>





  <scm>     
      <!--SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和列表。该连接只读。-->     
      <connection>     
          scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)      
      </connection>     
      <!--给开发者使用的,类似connection元素。即该连接不仅仅只读-->    
      <developerConnection>     
          scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk      
      </developerConnection>    
      <!--当前代码的标签,在开发阶段默认为HEAD-->    
      <tag/>           
      <!--指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。-->     
      <url>http://svn.baidu.com/banseon</url>     
  </scm> 
  

  <!--项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。-->     
  <distributionManagement>    
    <!--部署项目产生的构件到远程仓库需要的信息-->    
      <repository>    
        <!--是分配给快照一个唯一的版本号(由时间戳和构建流水号)?还是每次都使用相同的版本号?参见repositories/repository元素-->    
        <uniqueVersion/>    
        <id>banseon-maven2</id>     
        <name>banseon maven2</name>     
          <url>file://${basedir}/target/deploy</url>     
          <layout/>    
      </repository>    
      <!--构件的快照部署到哪里?如果没有配置该元素,默认部署到repository元素配置的仓库,参见distributionManagement/repository元素-->     
      <snapshotRepository>    
        <uniqueVersion/>    
        <id>banseon-maven2</id>    
          <name>Banseon-maven2 Snapshot Repository</name>    
          <url>scp://svn.baidu.com/banseon:/usr/local/maven-snapshot</url>     
        <layout/>    
      </snapshotRepository>    
      <!--部署项目的网站需要的信息-->     
      <site>    
    <!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置-->     
        <id>banseon-site</id>     
          <!--部署位置的名称-->    
          <name>business api website</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>

  <build>
    <!--当项目没有规定目标(Maven2 叫做阶段)时的默认值-->
    <defaultGoal>install</defaultGoal>
    <!--build目标文件的存放目录,默认在 ${basedir}/target 目录-->
    <directory>${basedir}/target</directory>
    <finalName>${artifactId}-${version}</finalName>
    <filters>
      <filter>filters/filter1.properties</filter>
    </filters>

    <!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。-->    
    <resources>    
      <!--这个元素描述了项目相关或测试相关的所有资源路径-->    
      <resource>    
        <!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。举个例 子,如果你想资源在特定的包里(   org.apache.maven.message,你就必须该元素设置为org/apache/maven /messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。-->    
        <targetPath/>    
        <!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。-->    
        <filtering/>    
        <!--描述存放资源的目录,该路径相对POM路径-->    
        <directory/>    
        <!--包含的模式列表,例如**/*.xml.-->    
        <includes/>    
        <!--排除的模式列表,例如**/*.xml-->    
        <excludes/>    
      </resource>    
    </resources>    
    <!--这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。-->    
    <testResources>    
      <!--这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明-->    
      <testResource>    
        <targetPath/>
        <filtering/>
        <directory/>
        <includes/>
        <excludes/>    
      </testResource>    
    </testResources>

    <plugins>
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
          <configuration>
              <tagBase>${git.conn}</tagBase>
              <branchBase>${git.conn}</branchBase>
              <username>${git.username}</username>
              <password>${git.password}</password>
          </configuration>
      </plugin>
      ...
    </plugins>

    <!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置-->
    <pluginManagement>
      <plugins>
        ...
      </plugins>
    </pluginManagement>

  </build>

</project>


参考

  1. POM Reference -- Apache Maven Project
  2. pom.xml 详解 -- adeyi
  3. Maven实战 -- 许晓斌
  4. dependency 中的 classifier属性
  5. 利用maven的filter和profile实现不同环境使用不同的配制
  6. 使用 maven profile
  7. Maven多环境配置实战 filter
  8. Maven Dependency Scope
  9. Maven基本命令 仓库 坐标 依赖 聚合 继承 pom.xml详解
  10. Maven pom.xml 配置详解
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,600评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,748评论 6 342
  • 当前,JVM生态圈主要的三大构建工具: Apache Ant(带着Ivy) Maven Gradle 对于刚开始接...
    清枫_小天阅读 5,774评论 1 13
  • 第一次用简书,希望找到一块净土,告别朋友圈说说,找到一块没有自己熟识的朋友的土地,来写写自己的生活,和不认识的朋友...
    田戏戏的喜剧生活阅读 274评论 0 0
  • 可以通过点击官方链接查看详细信息 官方提供的API列表如下: interfaces– Core gensim in...
    Midorra阅读 2,502评论 0 0