IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Maven中的pom.xml文件超详细解析 -> 正文阅读

[Java知识库]Maven中的pom.xml文件超详细解析

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

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


请添加图片描述

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

请添加图片描述

参考文章

  • 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的分享,后续还会有补充,如有欠缺欢迎评论区留言指正!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 10:55:44  更:2021-12-10 10:56:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:31:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码