Skip to content

Maven – POM Reference

POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了 Maven 项目的所有信息,包含项目的基本信息,项目依赖、项目如何构建

pom.xml 中有众多配置项,按作用可以分为几个类型,以下是一份 pom.xml 中包含的主要元素:

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion> <!-- pom当前模型版本,不要动他 -->

  <!-- 一、基础配置 -->
  <groupId>...</groupId>  
  <artifactId>...</artifactId>  >
  <version>...</version> 
  <packaging>...</packaging> <!-- 打包方式 -->
  <dependencies>...</dependencies>  <!-- 依赖列表 -->
  <parent>...</parent>  <!-- 继承的maven父项目 -->
  <dependencyManagement>...</dependencyManagement> <!-- 依赖管理 -->
  <modules>...</modules> <!-- 子模块列表 -->
  <properties>...</properties> <!-- 自定义属性列表 -->

  <!-- 二、项目构建 -->
  <build>...</build> <!-- 构建设置 -->
  <reporting>...</reporting> <!-- 报告设置 -->

  <!-- 其他项目信息 -->
  <name>...</name> 
  <description>...</description>
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>

  <!-- 环境配置-->
  <issueManagement>...</issueManagement>  
  <ciManagement>...</ciManagement>  <!-- 持续集成管理 -->
  <mailingLists>...</mailingLists>
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <repositories>...</repositories> <!-- 配置maven仓库,通常设置为阿里云 -->
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>  <!-- 配置文件列表 -->
</project>

基础配置

项目描述信息(maven 坐标)

POM 文件必须具有 project 元素和四个必需字段,用于描述项目的基本信息。

  • modelVersion :模型版本,不用动它
  • groupId
  • artifactId
  • version
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.companyname.project-group,maven会将该项目打成的jar包放本地路径:/com/companyname/project-group -->
    <groupId>com.companyname.project-group</groupId>
 
    <!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
    <artifactId>project</artifactId>
 
    <!-- 版本号 -->
    <version>1.0</version>
</project>

Packaging

Packaging元素用于定义项目构建格式,通常设为 warjar

依赖管理

依赖管理是 maven 的核心功能之一,maven 具有强大且灵活的依赖管理机制,处理依赖的方式:直接引入依赖、传递依赖(引入依赖的依赖)、依赖继承、聚合(多模块)。 我们通过使用 pom 中dependenciesparentdependencyManagementmodules等元素支持这些特性。

dependencies

dependencies是 pom 的基石,用于定义项目所依赖的外部库或模块。在dependencies列表下的dependency中我们指定需要引入的库的坐标、版本号,maven 会根据这些信息从中央仓库下载依赖到本地仓库,再关联到我们的项目中。

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
      <optional>true</optional>
    </dependency>
    ...
  </dependencies>
  ...
</project>

上边例子中我们引入了 Junit 库,注意 junit 库本身所依赖的其他库也会被引入。 注意到 dependency元素下除了库的坐标外还有一些其他信息:

  1. scope:依赖关系,可以理解为引入的依赖的类型,maven 对于不同的依赖关系会进行不同的处理。Maven定义了几种依赖关系,分别是:
  • compile,默认值,这种依赖项在所有阶段(编译、测试、运行)均可见,会随项目一起打包。
  • test,表示仅在测试时使用,Maven 再构建时不会将这种类型依赖打包;
  • runtime,在运行和测试阶段可见,但不参与编译。这些依赖项会在运行时才被加载。最典型的runtime依赖是JDBC驱动,例如MySQL驱动:
  • provided:在编译和测试阶段可见,但在打包阶段不会包含在最终的部署包中,通常由运行时提供。。最典型的provided依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要:
  • system:类似于 provided,但需要显式提供路径指向本地系统中的该依赖项。
  • import:只用于在dependencyManagement中进行依赖导入,不实际引入依赖。

注:上文中提到的编译、测试、运行、打包等涉及到 maven 项目构建过程,maven 项目构建过程包括【清理项目】→【编译项目】→【测试项目】→【生成测试报告】→【打包项目】→【部署项目】


  1. **optional****:**当该项目本身是依赖项时,将依赖项标记为可选
  2. exclusions:有时我们引入一个依赖时并不想引入它的传递依赖,这时可以通过exclusions元素排除它,比如有一个项目依赖于 Spring Boot Starter Web,而 Spring Boot Starter Web中包含了 Tomcat 作为默认的嵌入式容器。但是我们想要需要Jetty 作为 web 容器,这时可以使用 exclusions 来排除掉 Tomcat。
xml
<project>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.5.6</version>
            <!-- 排除Spring Boot Starter Web中的Tomcat -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 添加Jetty作为外部的Web容器依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <version>2.5.6</version>
        </dependency>
    </dependencies>
</project

parent

支持继承是 Maven 在管理依赖方面一个突出的能力,当我们有一些公用的一些依赖构建配置等,我们可以构建一个父 maven 项目,在父 maven 项目中引入这些公用的内容,子项目通过直接继承简化重复声明的不便。

注意,对于父项目 pom 或聚合项目 pom 文件中packaging 属性通常设为 pom,从而限定在打包阶段不会执行打包。

比如我们开发 springboot 项目,通常会继承springboot-parent,它提供了一系列常用的配置和依赖管理,包含大量常用库的版本定义、默认插件配置、默认属性和环境配置等。

xml
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.4.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>

dependency management

dependency management元素提供了一套用于集中管理项目依赖版本的机制,用于定义项目或子模块中的依赖版本和范围,但不实际引入这些依赖。 dependencyManagement 元素通常出现在父 POM 或聚合项目的 POM 文件中,当子模块引用一个在 dependencyManagement 中定义的依赖时,只需要引用依赖的坐标(不必指定版本),Maven 将自动使用 dependencyManagement 中定义的版本,从而避免在每个子模块中重复指定版本号,从而减少版本冲突。

xml
<!-- 父pom -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.5.6</version> <!-- 仅仅是声明版本号 -->
    </dependency>
  </dependencies>
</dependencyManagement>

<!-- 在子模块中使用时 -->
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 不需要指定版本号 -->
  </dependency>
</dependencies>

🐽与 paren 不同,parent 属性直接继承父项目的所有配置,dependency management 只用于设置版本信息,但不实际引入这些依赖

聚合(多模块)

Maven 多模块项目是指一个 Maven 项目下包含多个子模块,每个子模块可以是一个独立的项目单元,而聚合项目可以统一管理这些子模块,这种结构有助于组织复杂的项目,提高代码的维护性。 在聚合项目的 pom 文件中使用modules中声明子模块列表

不需要考虑子模块间的依赖关系和在 modules 中的声明顺序,maven 会自动的处理他们。

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 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</module>
  </modules>
</project>

关于多模块项目文档结构需要遵循相对路径,如下:

.
 |-- my-module
 |   -- pom.xml
 |-- another-project
 |  --pom.xml
 |-- third-project
 |  --pom.xml
 -- pom.xml

如果模块文档目录结构变为:

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

则父项目 pom 中要如此声明:

xml
<modules>
  <module>../my-module</module>
</modules>

properties

properties 用于在 pom 中定义一些属性(变量),从而在 pom 文件中的其他位置可以直接引用:

xml
<properties>
  <swagger.version>3.0.0</swagger.version>
</properties>

<dependencies>
  <!-- Swagger3依赖 -->
  <dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>${swagger.version}</version>
  </dependency>
</dependencies>

构建配置-build