JAVA—Maven相关知识(Pom.xml)
本文介绍Maven中Pom.xml配置文件的每个标签的含义,方便大家在碰到Maven项目时对属性有了解。
<modelVersion>(必填)
该标签明确了 POM(Project Object Model)文件所遵循的版本。当前,Maven 强制要求此标签的值固定为 4.0.0
<groupId>(必填)
用来定义项目所属的组织、公司或者团队,一般采用反向域名的形式,例如 com.example.circle
。作用:与 <artifactId>
和 <version>
一同构成项目的唯一坐标,帮助 Maven 在仓库中精准定位项目。
<version>(必填)
- <version>表示项目的版本号,版本号可以是具体的数字组合,如
1.0.0
,也可以是快照版本,如2.3.5 - SNAPSHOT
- <groupId> 和 <version> 共同确定项目在仓库中的位置,是项目坐标的重要组成部分。
<artifactId>(必填)
<artifactId>作为项目的唯一标识符,通常是项目的名称或者模块名称。
<parent>
这个标签用于解决父项目的继承(如果没有集成那么这个标签并不是必须的),告知父项目是谁,这样当前项目就可以实现配置的继承和共享,避免在多个子项目中重复编写相同的配置,子项目可以继承父项目的 <groupId>
、<version>
、<dependencies>
、<dependencyManagement>
、<build>
、<properties>
、<repositories>
和 <pluginRepositories>
等配置信息,减少重复配置(子项目可以从父项目继承 <groupId>
和 <version>
信息。如果子项目和父项目使用相同的组织标识和版本号,那么在子项目的 pom.xml
文件中可以不写 <groupId>
和 <version>
标签,但注意<artifactId>
必须填写)。
<parent>中存在以下的子标签,我们分别看看他们的作用。
<groupId>,<artifactId> 和 <version>
- 这三个标签与前面讲解的一样,用于表明父项目是谁,<groupId>,<artifactId> 和 <version>共同构成了父项目的坐标
<relativePath>(可选)
- 含义:指定父项目
pom.xml
文件相对于当前项目pom.xml
文件的相对路径。默认值为../pom.xml
,表示父项目的pom.xml
文件位于当前项目的上一级目录。 - 作用:当父项目和子项目在同一文件系统中时,Maven 可以通过该路径找到父项目的
pom.xml
文件。如果父项目是从远程仓库获取的,可以不指定该标签。
<properties>
<properties>
标签用于定义项目中的属性,这些属性可以在 pom.xml
文件的其他地方引用(使用$ { xxxx }的形式)。除了自定义属性以外,这里还有些配置编译和运行环境的属性可以在这里配置。除了这里配置的属性,我们还可以在这里引用系统属性,如操作系统信息、用户信息(类似于重新命名了,比如下例中,我们就可以在我们自己的pom.xml中使用$ { os.sys.name }索引到系统名了)
<properties>
<app.name>MyApp</app.name> <!-- 自定义属性, 在后文或者子项目中可以使用${app.name}的索引到 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 后文没有显示的调用该属性名,但在运行时会查到这个属性 -->
<os.sys.name>${os.name}</os.sys.name> <!-- 自定义属性名os.sys.name,这里可以直接索引到系统属性 -->
</properties>
<repositories>
这个标签解决的是maven应该从哪里下包的问题,pom.xml中通过<repositories>
可以指定当前的项目在下载包时向某个地址开仓库去下载,这个标签下每个<repository>
代表了一个仓库的详细定义,一般<repositories>
下可以包含多个<repository>
,下面是常见的repositories格式:
<repositories>
<repository>
<id>仓库唯一标识:custom-repo</id>
<name>仓库名称:Custom Maven Repository</name>
<url>仓库地址:https://example.com/maven-repo</url>
<releases>
<enabled>true</enabled>
<updatePolicy>更新策略:daily</updatePolicy>
<checksumPolicy>处理校验和错误的策略:fail</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
...
</repository>
</repositories>
上述配置的意思是:定义了一个名为 custom-repo
的仓库,地址为 https://example.com/maven-repo
,允许下载发布版本,每天检查一次更新,校验和错误时构建失败,不允许下载快照版本。下面介绍<repository>
中的每个标签含义:
<id>
<name>
<url>
<releases> 和 <snapshots>
- 含义:这两个元素用于分别配置正式版本(releases)和快照版本(snapshots)的仓库策略,包括是否启用该类型版本的下载以及更新频率。
<enabled>
:布尔值,指示是否允许从该仓库下载相应类型的版本。<updatePolicy>
:指定检查更新的频率,可选值有 always(每次构建都检查)、daily(每天检查一次)、interval:X(每隔 X 分钟检查一次)、never(从不检查)。<checksumPolicy>
:指定处理校验和错误的策略,可选值有 ignore(忽略校验和错误)、fail(校验和错误时构建失败)、warn(校验和错误时给出警告)。
- 是否必选:否。如果不配置,Maven 会使用默认策略。
总结:
<repository>标签中最重要的应该是<id>
和<url>
,其中<id>
作为仓库的唯一标识符,用于在整个 Maven 体系中区分不同仓库,同时也用于在 settings.xml 里关联认证信息以及在镜像配置中指定镜像目标,所以这里定义的<id>
中的值,会匹配到settings.xml 里的<mirrorOf>
,用于将<url>
地址进行替换,从而实现镜像下载。而<url>
则表示的是仓库的具体网络地址,Maven 会依据此地址从相应服务器下载依赖,但如果在 settings.xml 里配置的镜像匹配上了,那么就会使用匹配上的镜像地址进行下载(如果settings.xml 里的<mirrorOf>
的内容匹配上当前<repository>
中的<id>
内容)
其他要点:
- 当一个 pom.xml 文件中有多个
<repository>
标签时,Maven 在下载包时会尝试顺序规则 - 在存在多个层级 pom.xml 文件(即多模块 Maven 项目)的情况下,不同层级 pom.xml 文件里
<repository>
的 id 是可以相同的,但不推荐。此时涉及到的下载优先级问题,会根据就近原则 + 父项目传递的方式,也就是先在当前pom.xml文件中查找,如果没有找到则会向上层父项目中的pom.xml中寻找。
<dependencies>
这个标签应该算是Pom.xml文件中是至关重要的一个了,主要用于声明项目所依赖的外部库。<dependencies>
标签的核心作用是管理项目的依赖关系。通过在该标签下声明依赖,Maven 能够自动从配置的仓库(如 Maven 中央仓库、自定义仓库等也就是前文<repository>
中配置的)下载所需的库文件,并将它们包含到项目的构建路径中,从而保证项目可以正常编译、运行和测试。
<dependencies>
标签中包含多个 <dependency>
子标签,每个 <dependency>
子标签代表一个具体的依赖项。而<dependency>
的子标签有以下几个非常重要的:
<groupId>、<artifactId>和<version>
这三个标签就能锁定所依赖第三方库的准确版本,含义与前文介绍的一样,<groupId>
:标识依赖项所属的组织或公司,<artifactId>
:第三方包模块的唯一标识依赖项的名称,<version>
:指定依赖项的版本号。
<scope>(可选)
这个标签用于定义当前依赖项的作用范围,常见的作用范围有 compile
(默认值,编译、测试、运行时都需要)、test
(仅在测试时需要)、runtime
(运行时需要,编译时不需要)、provided
(编译和测试时需要,但运行时由容器提供)等。
<optional>(可选)
布尔值,指示该依赖是否为可选依赖。如果设置为 true
,则依赖不会传递给依赖当前项目的其他项目,一般不会设置,保持为默认值fasle,即依赖当前项目的其他项目也会间接引入该依赖。比如:在 project-a
中,引入了 fastjson
依赖,并将其设置为可选依赖。这表示 fastjson
是 project-a
自身可能会使用的库,但对于依赖 project-a
的其他项目来说,并不一定需要这个库。此时有个项目project-b
依赖于 project-a
,由于 project-a
中的 fastjson
依赖被设置为可选依赖,所以 project-b
不会自动引入 fastjson
依赖。同样,又有另一个项目project-c
依赖于 project-b
,也不会因为 project-a
引入了 fastjson
而自动引入该依赖。如果 project-b
或者 project-c
需要使用 fastjson
,则需要在它们各自的 pom.xml
中显式声明该依赖。
<exclusions>(可选,但重要)
用于排除传递性依赖。当依赖项引入了其他不必要的依赖时,可以使用该标签排除这些依赖,正如上面的例子如果我并没有在project-a
中把fastjson这个依赖设置为可选的,那么后续的project-c
和 project-b
都会因为引入了project-a
而被迫引入fastjson,需要注意的的这种引入,在一般情况下开发人员是无法注意到fastjson被引入了(不经意间)。如果此时project-b
中又引入了一个新的fastjson版本,而这两个fastjson版本就可能产生冲突,虽然maven会根据一定规则帮我们确定到底使用哪一个依赖,但在某些复杂的多模块项目中可能无法正确处理冲突,导致构建失败或出现不可预测的行为。所以当产生冲突时我们需要尽量使用这个标签对其进行排除。
<exclusions>
中包含一个或多个 <exclusion>
子标签,每个 <exclusion>
子标签通过 <groupId>
和 <artifactId>
来唯一标识要排除的依赖。
<dependency>
<groupId>主依赖的组 ID</groupId>
<artifactId>主依赖的构件 ID</artifactId>
<version>主依赖的版本号</version>
<exclusions>
<exclusion>
<groupId>要排除的依赖的组 ID</groupId>
<artifactId>要排除的依赖的构件 ID</artifactId>
</exclusion>
<!-- 可以有多个 <exclusion> 标签 -->
</exclusions>
</dependency>
<dependencyManagement>
从名字上来说这个标签与<dependencies>
非常像,但作用却完全不同,<dependencies>
直接声明项目的依赖项,Maven 会根据这些声明下载并包含依赖到项目中。而 <dependencyManagement>
中声明的依赖主要用于让子项目可以继承这些配置,但子项目需要显式声明依赖才能引入。
在一个大型的 Maven 项目或者多模块项目中,可能存在多个模块需要引入相同的依赖。如果每个模块都单独指定依赖的版本,可能会导致不同模块使用不同版本的同一依赖,从而引发兼容性问题。通过 <dependencyManagement>
标签,可以在父项目或者根项目中统一管理依赖的版本,子项目只需引用依赖而无需指定版本,这样能确保所有模块使用相同版本的依赖。并且当需要升级某个依赖的版本时,只需在 <dependencyManagement>
中修改一处即可,而不需要在每个子项目中逐一修改,提高了可维护性。<dependencyManagement>
它包含一个重要的子标签 <dependencies>
,而 <dependencies>
又包含多个 <dependency>
子标签。
<dependencies>
与之前提到的<dependencies>
一样,作为一个容器,包含有多个<dependency>
子标签,每个<dependency>
的子标签的内容也是与之前的一样包括:<groupId>
<artifactId>
<version>
<scope>
<optional>
<exclusions>
含义可以参看前文
<description>,<url>
<description>对项目进行简要描述,说明项目的功能、用途等信息。<url>项目的 URL 地址,通常指向项目的官方网站或者代码仓库地址,这里几个一般都不需要特地的写。
<name>
项目的友好名称,用于在日志、报告等输出中显示,方便开发者识别项目。推荐写项目/模块名
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南