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>

  • 含义:仓库的唯一标识符。在整个 Maven 项目中,每个仓库的 <id> 必须是唯一的。这个 <id> 用于在 settings.xml 文件中关联认证信息,以及在 <mirrorOf> 配置中指定要镜像的仓库。
  • 是否必选:推荐设置,但不是严格必选。如果不设置,Maven 会默认使用仓库的 <url> 作为 <id>,不过这可能会带来管理上的不便,并且在运行时会收到警告信息,一般设置central,snapshots或者releases这种标签,也方便在settings.xml中指定镜像时方便。

<name>

  • 含义:仓库的友好名称,主要用于在日志或其他输出中显示,方便开发者识别仓库。
  • 是否必选:否。它只是一个描述性的标签,不影响 Maven 对仓库的实际使用。

<url>

  • 含义:仓库的具体 URL 地址,Maven 会从这个地址下载依赖。这个地址应该指向一个符合 Maven 仓库规范的服务器。
  • 是否必选:是。如果没有指定 <url>,Maven 就无法知道从哪里下载依赖,会导致依赖下载失败。

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

  项目的友好名称,用于在日志、报告等输出中显示,方便开发者识别项目。推荐写项目/模块名

 

posted @   Circle_Wang  阅读(104)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示