Maven 中的 pom
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<build>...</build>
<reporting>...</reporting>
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<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 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>nacospro</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>nacospro</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
</dependency>
</dependencies>
</project>
[](()5、自定义的属性变量
=============================================================================
我们可以在 POM 的元素下自定义 Maven 属性
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hutool.version>5.0.6</hutool.version>
<pagehelper.version>1.3.0</pagehelper.version>
</properties>
[](()6、依赖管理
=========================================================================
依赖关系:描述了项目相关的所有依赖,组成了项目构建过程中的一个个环节;它们会自动从项目定义的仓库中下载,一个项目可以设置多了依赖;
可通过[https://mvnrepository.com/](()寻找依赖,获得相应的坐标;具体操作可阅读[Maven 的安装配置、IDEA 中搭建 Maven 环境](()一文;
[](()6.1、整体依赖关系列表
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<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 个常用的可选范围:
compile:默认值,表示编译依赖范围;适用于所有阶段(编译、测试、运行),会随着项目一起发布。表明该 jar 包一直全程存在/需要;
provided:表示已提供依赖范围;编译、测试时需要,运行时不需要,不会被打包。如 servlet.jar;
runtime:表示运行时提供依赖范围;只在运行时使用,如 JDBC 驱动,适用运行和测试阶段;
test:表示测试依赖范围;测试时有效,用于编译和运行测试代码。不会随项目发布;
system:类似 provided,需要显式提供包含依赖的 jar,Maven 不会在 Repository 中查找它(不推荐);
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 所包含坐标,排除依赖包中所包含的依赖 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 关系 ,不需要添加版本,直接类别排除 ,排除依赖可以设置当前依赖中是否使用间接依赖。注意和可选依赖区分,可以达到同样的效果。
[](()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>
<exclusion>
<groupId>com.sx.kak</groupId>
<artifactId>X</artifactId>
</exclusion>
评论