Maven中的pom.xml文件超详细解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 我们在平时的开发中都会或多或少的使用maven来管理和构建我们的项目,即使使用了各种框架jar包也是通过Maven来引入的,所以我觉得有必要了解pom.xml文件中的每一项配置,来帮助我更好的使用Maven这个自动化工具;

Maven中的pom.xml文件超详细解析

      我们在平时的开发中都会或多或少的使用maven来管理和构建我们的项目,即使使用了各种框架jar包也是通过Maven来引入的,所以我觉得有必要了解pom.xml文件中的每一项配置,来帮助我更好的使用Maven这个自动化工具;


@[toc]

请添加图片描述

1、Maven的下载安装

      首选我们需要搭建一个Maven环境,由于本篇侧重于分享解析pom.xml里面的元素,对Maven的下载安装不做过多的阐述,可以参考Maven的安装配置、IDEA中搭建Maven环境一文自行操作,如有问题可以评论区留言;

2、什么是pom?

      POM全程Project Object Model,又称项目对象模型。他是Maven工程的基本工作单元,是一个XML(可扩展标记语言)文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖等等。执行任务或目标时,Maven会在当前目录中查找 POM并读取从而获取所需的配置信息执行目标,属于项目级别的配置文件。

      总之pom最厉害的是提供一站式支持,可用于管理:源代码、配置文件、缺陷跟踪系统(defect tracking system)、组织和许可证(licenses)、项目所在的URL地址、开发者的信息和角色、项目依赖以及其他所有的和代码生命周期相关的方面。而在Maven中就只需要一个pom.xml文件,可以说pom.xml就是Maven的核心!

  • 一个完整的pom.xml文件放在项目的根目录下;

3、较完整的pom元素

pom的整体结构,更详细pom可见 超级POM_POM文件总体配置说明.pdf

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

4、默认生成Maven工程的pom内容

其中groupId,artifactId,version组成了项目的唯一坐标。

<?xml version="1.0" encoding="UTF-8"?>
<!--project是pom.xml根元素,它包含了pom.xml的一些约束信息,声明了一些POM相关的命名空间以及xsd元素-->
<!-- xmlns  命名空间,类似包名-->
<!-- xmlns:xsi    xml遵循的标签规范-->
<!--xsi:schemaLocation    定义xmlschema的地址,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">
    <!-- 指定了当前pom.xml版本,目前固定为4.0.0版本。-->
    <modelVersion>4.0.0</modelVersion>
    <!--  坐标  -->
    <!--  属于哪个组,一般是项目所在组织或公司域名的倒序  -->
    <groupId>com.sx.kak</groupId>
    <!--  定义当前项目在组中的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
    <artifactId>nacospro</artifactId>
    <!--  定义项目当前的版本  -->
    <version>1.0-SNAPSHOT</version>
    <!--  打包类型,可取值:pom , jar , maven-plugin , ejb , war , ear , rar , par等等  -->
    <packaging>jar</packaging>
    <!--  项目的名称(可省略) 默认artifactId,可修改为用户友好的名称 -->
    <name>nacospro</name>
    <!--  仓库的地址(可省略)  -->
    <url>http://maven.apache.org</url>

    <!--定义的依赖清单,有所依赖包都需要写在这个标签里面-->
    <dependencies>
        <!--具体的依赖 -->
        <dependency>

        </dependency>

    </dependencies>

</project>

5、自定义的属性变量

我们可以在POM的元素下自定义Maven属性

<!--  定义的属性变量,在其他地方进行使用  -->
<properties>
    <!--  Java版本  -->
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!--    通过${hutool.version}来使用    -->
    <hutool.version>5.0.6</hutool.version>
    <!--    通过${pagehelper.version}来使用    -->
    <pagehelper.version>1.3.0</pagehelper.version>
</properties>

6、依赖管理

依赖关系:描述了项目相关的所有依赖,组成了项目构建过程中的一个个环节;它们会自动从项目定义的仓库中下载,一个项目可以设置多了依赖;

6.1、整体依赖关系列表

<!--定义的依赖清单,有所依赖包都需要写在这个标签里面-->
<dependencies>
    <!--HuTool工具包 -->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>${hutool.version}</version>
    </dependency>

    <!--pagehelper-->
    <dependency>
        <!--依赖项的组织名-->
        <groupId>com.github.pagehelper</groupId>
        <!--依赖项的子项目名-->
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <!--依赖项的版本-->
        <version>${pagehelper.version}</version>
        <!-- 依赖项的适用范围 -->
        <scope>test</scope>
        <!-- 可选依赖 ,对外隐藏当前所依赖的资源,是不透明的;如果别人依赖了本项目,被配置的不会在别人的项目中依赖到-->
        <optional>true</optional>
        <!-- 排除依赖,主动断开依赖的资源,排除项目中的依赖冲突时使用,不依赖该项目,被排除的资源不需要指定版本-->
        <exclusions>
            <exclusion>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

6.2、依赖关系的传递性

直接依赖:在当前项目中通过依赖配置建立的依赖关系;

间接依赖:当前工程pom配置了依赖A,A又依赖B,则本工程也依赖B,B为本工程的间接依赖。

如下图:A依赖于B,B又依赖于C,此时B是A的直接依赖,C是A的间接依赖。

请添加图片描述

        我们都知道在Maven中依赖是有传递性的,不管Maven项目存在多少间接依赖,POM中都只需要定义其直接依赖,不必定义任何间接依赖,Maven会动读取当前项目各个直接依赖的POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中,能够帮助用户简化POM的配置。

      上图A、B、C三者的依赖关系,根据Maven的依赖传递机制,我们只需要在项目A的 POM 中定义其直接依赖B,在项目 B的POM中定义其直接依赖C,Maven会解析A的直接依赖B的POM ,将间接依赖C以传递性依赖的形式引入到项目A中。

6.3、依赖传递可能造成的问题

      通过依赖传递关系,可以使依赖关系树迅速增长到一个很大的量级,但很有可能会出现依赖重复,依赖冲突等情况,Maven针对这些情况提供了如下功能进行处理:

  • 依赖范围(Dependency scope)
  • 依赖调解(Dependency mediation)
  • 可选依赖(Optional dependencies)
  • 排除依赖(Excluded dependencies)
  • 依赖管理(Dependency management)

6.3.1、scope依赖范围

      我们可以在POM的依赖声明使用scope元素来控制依赖与三种classpath(编译 classpath、测试 classpath、运行 classpath )之间的关系,这就是依赖范围。

scope依赖项有6个常用的可选范围:

  1. compile:默认值,表示编译依赖范围;适用于所有阶段(编译、测试、运行),会随着项目一起发布。表明该jar包一直全程存在/需要;
  2. provided:表示已提供依赖范围;编译、测试时需要,运行时不需要,不会被打包。如servlet.jar;
  3. runtime:表示运行时提供依赖范围;只在运行时使用,如JDBC驱动,适用运行和测试阶段;
  4. test:表示测试依赖范围;测试时有效,用于编译和运行测试代码。不会随项目发布;
  5. system:类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它(不推荐);
  6. optional:当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用;

依赖范围与三种classpath 的关系:

请添加图片描述

6.3.2、依赖调节

      Maven中用户只需要关心项目的直接依赖,而不必关心这些直接依赖会引入哪些间接依赖。但当一个间接依赖存在多条引入路径时,为了避免出现依赖重复的问题就会通过依赖调节来确定间接依赖的引入路径。

6.3.2.1、路径优先

当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高;

A存在以下的依赖关系
情况一:A->B->C->D
情况二:A->E->D
  • D是A的间接依赖,但两条引入情况上有两个不同的版本,不可以同时引入,否则造成重复依赖的问题。根据Maven依赖调节的第一个原则:引入路径短者优先,情况一的路径长度为 3,情况二的路径长度为2,因此间接依赖D将从A->E->D路径引入到A中。

6.3.2.2、声明优先

当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的;

A存在以下依赖关系
情况一:A->B->D
情况二:A->C->D

<dependencies>
    ...      
    <dependency>
        ...
        <artifactId>B</artifactId>       
        ...
    </dependency>
    ...
    <dependency>
        ...
        <artifactId>X</artifactId>
        ...
    </dependency>
    ...
</dependencies>
  • D是A的间接依赖,其两条引入路径的长度都是2,此时路径优先已经无法解决,需要使用先声明者优先;由以上配置可以看出,由于B的依赖声明比C靠前,所以情况一的间接依赖将从A->B->D路径引入到A中。

优先使用第一条原则解决,第一条原则无法解决,再使用第二条原则解决;

6.3.2.3、特殊优先

当资源配置了相同资源的不同版本,后配置的覆盖先配置的(不做举例);

6.3.3、可选依赖(6.4.2中详解)

在依赖中配置optional为true/false 是否向下传递,如果配置为true,则别人依赖了本项目,被配置的不会在别人的项目中依赖到。如果为false表示可以向下传递称为间接依赖;

6.3.4、排除依赖(6.4.1中详解)

exclusions所包含坐标,排除依赖包中所包含的依赖关系 ,不需要添加版本,直接类别排除 ,排除依赖可以设置当前依赖中是否使用间接依赖。注意和可选依赖区分,可以达到同样的效果。

6.4、排除依赖和可选依赖

      Maven依赖具有传递性,在不考虑依赖范围等因素的情况下,Maven根据依赖传递机制,会将间接依赖C引入到A中。但如果A希望将间接依赖C排除于是Maven提供了两种解决方式:排除依赖和可选依赖。

6.4.1、排除依赖

排除依赖是控制当前项目是否使用其直接依赖传递下来的间接依赖;

  • exclusions元素下可以包含若干个exclusion子元素,用于排除若干个间接依赖;

  • exclusion元素用来设置具体排除的间接依赖,该元素包含两个子元素:groupId 和 artifactId,用来确定需要排除的间接依赖的坐标信息;

  • exclusion元素中只需要设置groupId和artifactId 就可以确定需要排除的依赖,无需指定版本 version。

6.4.2、可选依赖

可选依赖用来控制当前依赖是否向下传递成为间接依赖;

  • optional 默认值为 false,表示可以向下传递称为间接依赖;
  • 若 optional 元素取值为 true,则表示当前依赖不能向下传递成为间接依赖。

6.4.3、排除依赖和可选依赖举例

假设A依赖于B,B依赖于X,B又依赖于Y。B 实现了两个特性,其中一个特性依赖于X,另一个特性依赖于Y,且两个特性是互斥的关系,用户无法同时使用两个特性,所以A需要排除X,此时就可以在A中将间接依赖X排除。

6.4.3.1、排除依赖举例

排除依赖是通过在A中使用 exclusions 元素实现的,该元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖,示例代码如下。

<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>
    <groupId>com.sx.kak</groupId>
    <artifactId>A</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.sx.kak</groupId>
            <artifactId>B</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <!-- 设置排除 -->
                <!-- 排除依赖必须基于直接依赖中的间接依赖设置为可以依赖为 false -->
                <!-- 设置当前依赖中是否使用间接依赖 -->
                <exclusion>
                    <!--设置具体排除-->
                    <groupId>com.sx.kak</groupId>
                    <artifactId>X</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

6.4.3.2、选依赖举例

在B的POM关于X的依赖声明中使用optional 元素,将其设置成可选依赖,示例配置如下。

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sx.kak</groupId>
    <artifactId>B</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>net.biancheng.www</groupId>
            <artifactId>X</artifactId>
            <version>1.0-SNAPSHOT</version>
            <!--设置可选依赖,true则表示当前依赖不能向下传递成为间接依赖  -->
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

6.4.3、排除依赖 VS 可选依赖

排除依赖和可选依赖都能在项目中将间接依赖排除在外,但两者实现机制却完全不一样。

  1. 排除依赖是控制当前项目是否使用其直接依赖传递下来的接间依赖;
  2. 可选依赖是控制当前项目的依赖是否向下传递;
  3. 可选依赖的优先级高于排除依赖
  4. 若对于同一个间接依赖同时使用排除依赖和可选依赖进行设置,那么可选依赖的取值必须为false,否则排除依赖无法生效。

7、Build插件配置

Build理解为构建项目需要的信息,主要用于编译设置;

7.1、Build的两个部分配置

      在Maven的pom.xml文件中,Build相关配置包含两个部分,一个是build,另一个是reporting。

<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">
  ...
  <!-- 称为Project Build,是<project>的直接子元素 -->
  <build>...</build>

  <profiles>
    <profile>
      <!-- 称为Profile Build,即是<profile>的直接子元素 -->
      <build>...</build>
    </profile>
  </profiles>
</project>

Profile Build包含了基本的build元素,而Project Build还包含两个特殊的元素,即各种Directory和extensions。

7.2、常用的Build结构

<!-- 构建项目需要的信息 --> 
<build>
    <!-- 使用的插件列表 -->
    <plugins>
        <!-- plugin元素包含描述插件所需要的信息 --> 
        <plugin>
            <!-- 插件在仓库里的group ID -->
            <groupId>org.springframework.boot</groupId>
            <!-- 插件在仓库里的artifact ID --> 
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
    <!-- 这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。 --> 
    <resources>
        <!-- 这个元素描述了项目相关或测试相关的所有资源路径 --> 
        <resource>
            <!-- 描述存放资源的目录,该路径相对POM路径 -->
            <directory>src/main/java</directory>
            <!-- 包含的模式列表,例如**/*.xml. --> 
            <includes>
                <include>**/*.xml</include>
            </includes>
            <!-- 是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出 --> 
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.*</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

8、写在最后_超级POM

      看到这里有没有觉得对pom的理解又上了一个层次,经常使用POM文件却对他是一知半解有时候就那么用了却不知道这个标签到底是啥意思;于是就有了去了解每一个标签的作用的想法,虽说还可能有所欠缺,但是确实让我对Maven有了更上一层的理解;我觉得还是有很多没有整理到,后期在继续学习整理吧!

      超级POM就是一个比较全的POM文件,如果有遇到不懂的,可以去文档里面搜索;如果有想要超级POM的小伙伴可见 超级POM_POM文件总体配置说明.pdf,或者评论区留下邮箱地址私发给你;

请添加图片描述

参考文章

以上就是我对pom.xml的分享,后续还会有补充,如有欠缺欢迎评论区留言指正!

目录
相关文章
|
30天前
|
Java
Java“解析时到达文件末尾”解决
在Java编程中,“解析时到达文件末尾”通常指在读取或处理文件时提前遇到了文件结尾,导致程序无法继续读取所需数据。解决方法包括:确保文件路径正确,检查文件是否完整,使用正确的文件读取模式(如文本或二进制),以及确保读取位置正确。合理设置缓冲区大小和循环条件也能避免此类问题。
|
1月前
|
SQL 关系型数据库 MySQL
数据库导入SQL文件:全面解析与操作指南
在数据库管理中,将SQL文件导入数据库是一个常见且重要的操作。无论是迁移数据、恢复备份,还是测试和开发环境搭建,掌握如何正确导入SQL文件都至关重要。本文将详细介绍数据库导入SQL文件的全过程,包括准备工作、操作步骤以及常见问题解决方案,旨在为数据库管理员和开发者提供全面的操作指南。一、准备工作在导
176 0
|
28天前
|
自然语言处理 数据处理 Python
python操作和解析ppt文件 | python小知识
本文将带你从零开始,了解PPT解析的工具、工作原理以及常用的基本操作,并提供具体的代码示例和必要的说明【10月更文挑战第4天】
249 60
|
1天前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
21 6
|
2天前
|
存储
文件太大不能拷贝到U盘怎么办?实用解决方案全解析
当我们试图将一个大文件拷贝到U盘时,却突然跳出提示“对于目标文件系统目标文件过大”。这种情况让人感到迷茫,尤其是在急需备份或传输数据的时候。那么,文件太大为什么会无法拷贝到U盘?又该如何解决?本文将详细分析这背后的原因,并提供几个实用的方法,帮助你顺利将文件传输到U盘。
|
14天前
|
缓存 IDE Java
idea的maven项目打包时没有source下的文件
【10月更文挑战第21天】idea的maven项目打包时没有source下的文件
30 1
|
21天前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
1月前
|
存储 搜索推荐 数据库
运用LangChain赋能企业规章制度制定:深入解析Retrieval-Augmented Generation(RAG)技术如何革新内部管理文件起草流程,实现高效合规与个性化定制的完美结合——实战指南与代码示例全面呈现
【10月更文挑战第3天】构建公司规章制度时,需融合业务实际与管理理论,制定合规且促发展的规则体系。尤其在数字化转型背景下,利用LangChain框架中的RAG技术,可提升规章制定效率与质量。通过Chroma向量数据库存储规章制度文本,并使用OpenAI Embeddings处理文本向量化,将现有文档转换后插入数据库。基于此,构建RAG生成器,根据输入问题检索信息并生成规章制度草案,加快更新速度并确保内容准确,灵活应对法律与业务变化,提高管理效率。此方法结合了先进的人工智能技术,展现了未来规章制度制定的新方向。
30 3
|
1月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
54 1

推荐镜像

更多