POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了 Maven 项目的所有信息,包含项目的基本信息,项目依赖、项目如何构建。
pom.xml 中有众多配置项,按作用可以分为几个类型,以下是一份 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 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
<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
元素用于定义项目构建格式,通常设为 war
或jar
依赖管理
依赖管理是 maven 的核心功能之一,maven 具有强大且灵活的依赖管理机制,处理依赖的方式:直接引入依赖、传递依赖(引入依赖的依赖)、依赖继承、聚合(多模块)。 我们通过使用 pom 中dependencies
、parent
、dependencyManagement
、modules
等元素支持这些特性。
dependencies
dependencies
是 pom 的基石,用于定义项目所依赖的外部库或模块。在dependencies
列表下的dependency
中我们指定需要引入的库的坐标、版本号,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 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
元素下除了库的坐标外还有一些其他信息:
scope
:依赖关系,可以理解为引入的依赖的类型,maven 对于不同的依赖关系会进行不同的处理。Maven定义了几种依赖关系,分别是:
compile
,默认值,这种依赖项在所有阶段(编译、测试、运行)均可见,会随项目一起打包。test
,表示仅在测试时使用,Maven 再构建时不会将这种类型依赖打包;runtime
,在运行和测试阶段可见,但不参与编译。这些依赖项会在运行时才被加载。最典型的runtime依赖是JDBC驱动,例如MySQL驱动:provided
:在编译和测试阶段可见,但在打包阶段不会包含在最终的部署包中,通常由运行时提供。。最典型的provided依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要:system
:类似于 provided,但需要显式提供路径指向本地系统中的该依赖项。import
:只用于在dependencyManagement中进行依赖导入,不实际引入依赖。
注:上文中提到的编译、测试、运行、打包等涉及到 maven 项目构建过程,maven 项目构建过程包括【清理项目】→【编译项目】→【测试项目】→【生成测试报告】→【打包项目】→【部署项目】
**optional**
**:**当该项目本身是依赖项时,将依赖项标记为可选exclusions
:有时我们引入一个依赖时并不想引入它的传递依赖,这时可以通过exclusions
元素排除它,比如有一个项目依赖于 Spring Boot Starter Web,而 Spring Boot Starter Web中包含了 Tomcat 作为默认的嵌入式容器。但是我们想要需要Jetty 作为 web 容器,这时可以使用 exclusions 来排除掉 Tomcat。
<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
,它提供了一系列常用的配置和依赖管理,包含大量常用库的版本定义、默认插件配置、默认属性和环境配置等。
<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
中定义的版本,从而避免在每个子模块中重复指定版本号,从而减少版本冲突。
<!-- 父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 会自动的处理他们。
<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 中要如此声明:
<modules>
<module>../my-module</module>
</modules>
properties
properties 用于在 pom 中定义一些属性(变量),从而在 pom 文件中的其他位置可以直接引用:
<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>