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

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


文章目录

  • Maven中的pom.xml文件超详细解析
  • 1、Maven的下载安装
  • 2、什么是pom?
  • 3、较完整的pom元素
  • 4、默认生成Maven工程的pom内容
  • 5、自定义的属性变量
  • 6、依赖管理
    • 6.1、整体依赖关系列表
    • 6.2、依赖关系的传递性
    • 6.3、依赖传递可能造成的问题
      • 6.3.1、scope依赖范围
      • 6.3.2、依赖调节
        • 6.3.2.1、路径优先
        • 6.3.2.2、声明优先
        • 6.3.2.3、特殊优先
      • 6.3.3、可选依赖(6.4.2中详解)
      • 6.3.4、排除依赖(6.4.1中详解)
    • 6.4、排除依赖和可选依赖
      • 6.4.1、排除依赖
      • 6.4.2、可选依赖
      • 6.4.3、排除依赖和可选依赖举例
        • 6.4.3.1、排除依赖举例
        • 6.4.3.2、选依赖举例
      • 6.4.3、排除依赖 VS 可选依赖
  • 7、Build插件配置
    • 7.1、Build的两个部分配置
    • 7.2、常用的Build结构
  • 8、写在最后_超级POM
  • 参考文章
  • 以上就是我对pom.xml的分享,后续还会有补充,如有欠缺欢迎评论区留言指正!

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.0http://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、依赖管理

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

  • 可通过https://mvnrepository.com/寻找依赖,获得相应的坐标;具体操作可阅读Maven的安装配置、IDEA中搭建Maven环境一文;

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,或者评论区留下邮箱地址私发给你;

参考文章

  • https://maven.apache.org/pom.html#What_is_the_POM
  • https://blog.csdn.net/jk418756/article/details/87917776
  • https://www.cnblogs.com/cy0628/p/15034450.html

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

Maven中的pom.xml文件超详细解析相关推荐

  1. Maven 中的pom.xml文件

    Maven中的Pom.xml文件解析 项目管理利器(Maven)--Pom.xml解析<name>项目的描述名</name> <url>项目的地址</url& ...

  2. IDEA导入Maven项目,pom.xml文件中 有inspects a maven model for resolution problems报错 !!!!!!!!!!有用

    IDEA导入Maven项目,pom.xml文件中 有inspects a maven model for resolution problems报错 2018年08月06日 22:13:09 东方不能 ...

  3. 在maven中的pom.xml配置ojdbc报错

    在maven工程的pom.xml文件配置oracle的ojdbc.jar文件报错(主要是因为oracle是要收费的),这就需要我们手动导入.(导入前的前提是你已经配置好了jdk以及maven的环境变量 ...

  4. Maven学习总结(十一)——Maven项目对象模型pom.xml文件详解

    2019独角兽企业重金招聘Python工程师标准>>> <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  5. maven项目的pom.xml文件添加依赖

    先把添加依赖的代码放到pom.xml文件里,不出意外会爆红,其实是因为你的maven-repository仓库里没有对应的jar包. 我用的是intellij idea 2022.3的版本,爆红时右上 ...

  6. IDEA中的pom.xml文件变成了橙色

    在pom.xml文件上单击鼠标右键,然后在弹出框中点击+ Add as Maven Project就可以了

  7. maven项目,pom.xml文件变成小虫子(蜘蛛)解决办法

    具体情况如下图: 造成这种情况的原因,可能是手误造成的,解决办法如下: 选中pom.xml文件,点击Mark as Plain Text 就解决了

  8. IDEA Maven项目中,pom.xml文件显示为橘红色普通xml文件,将pom文件变为蓝色图标

    一.创建Maven项目后,pom.xml显示为橘红的普通文件,可能是IDEA没有识别 二.如果可以依赖可以正常导入,文件还是显示为橘色,可能是开启了节能模式导致的 这时候取消勾选Power Save ...

  9. Maven中的pom.properties文件

    ■pom.properties 0.所在路径 xxx.jar/META-INF/maven/grooupId/artifactId/ 1.正常情况下,只包含下机项目 ・version ・grooupI ...

  10. pom文件找不到子项目_java,eclipse_eclipse中maven项目pom.xml文件找不到parent要怎么解决?,java,eclipse,maven - phpStudy...

    eclipse中maven项目pom.xml文件找不到parent要怎么解决? 在maven项目中方pom.xml文件找不到parent,maven clean报错如下: [ERROR] [ERROR ...

最新文章

  1. php ajax formdata 进度,使用formdata使用ajax将数据发送到PHP
  2. ssr面板_碧蓝航线:详解SSR里诺强不强 航母专用保姆 三流防空特化型轻巡
  3. Hibernate5.x Idea搭建
  4. oracle 列级外键,Oracle 中的外键与锁
  5. 移动设备页面高度不足时min-height 的尴尬处理
  6. Java 必须掌握的 12 种 Spring 常用注解
  7. IdnentiyServer-使用客户端凭据访问API
  8. java传参数的方法_java中方法的参数传递机制
  9. [论文阅读] Active Learning for Deep Object Detection via Probabilistic Modeling
  10. ROS-cmakelists的解释
  11. JSK-5 矩阵翻转【入门】
  12. RF中的 click element
  13. 百亿级微信红包的高并发资金交易系统设计方案
  14. Day77 Java框架 SSH案例_ERP(十一)_CXF框架_红日物流BOS系统_ERP物流信息管理
  15. 怎么将英文的PDF翻译成中文的
  16. 解决error while accessing a target resource. resource is perhaps not available or a wrong access was
  17. 使用VScode阅读Linux源码
  18. Linux Ubuntu 鼠标变为十字架锁死解决办法
  19. js 删除数组元素。
  20. 软件工程 | 第四章 系统设计

热门文章

  1. Android Studio 升级到3.0后出现编译错误\.gradle\caches\transforms-1\files-1.1\*****-release.aar
  2. Nodejs Playwright 自动识别验证码登陆B站
  3. 计算机很多术语都是cat,18 个开源翻译工具帮助你的项目本地化
  4. 微信小程序云存储(文件上传到云端)
  5. [老文档2016]一种后台管理智能杀进程的规则与方法
  6. sugon服务器型号从哪看,sugon服务器初始密码
  7. 由连连看游戏作弊器想到的
  8. Android开发:基站定位
  9. Mac 软件和学习经验分享
  10. 英特尔与世界自然基金会携手 用人工智能技术保护东北虎