Maven学习(五)————依赖的特性辨析

引言

在Maven 中,依赖有一些特性必须我们掌握,如依赖的传递性。

一、依赖的传递性

其实依赖的传递性非常好理解。

上图,如果 Maven 项目 B 已经依赖了 C ,A 又依赖了 B,那么 A 不需要再在自己的pom 中重复引入 C 的依赖声明,就可以直接使用 C 中的代码了。

显而易见,依赖能够传递的好处就是,不必反复声明相同的依赖,在“最下面” 的工程中依赖一次就可以。在实际开发中,往往会有一个专门管理依赖的模块项目。

不过这种情况不是绝对的,这里有一个非常关键的限制,即依赖的 Scope

Scope 指的是“作用域”,对于依赖来说,就指的是某个依赖是否参与 compile 、test、打包等几个重要的事件。

我们在pom 中声明 <dependency> 的时候,可以顺便声明<scope>,默认情况下是就是 compile 。对于 scope 是 compile 的依赖,上面的依赖传递关系是成立的,即 A 可以不必明确声明依赖 C 就能使用C 中的代码。

另外,虽然依赖的传递性非常方便,但并不适合所有场景,有些情况下,是需要进行直接依赖的,比如,当模块项目进行拆分重组,那么有些间接依赖可能就会被切断传递的链路,这种情况,就需要在搭建项目之初考虑到这个问题。

二、依赖的作用域

我在网上看到一些对maven 依赖的 scope 属性的讲解,貌似都不太敢于称其为“作用域”,不过我觉得“作用域”这个翻译应该是比较合适的。

引述一下官网的描述:

Dependency scope is used to limit the transitivity of a dependency, and also to affect the classpath used for various build tasks.

依赖作用域用来限制一个依赖的传递性,同时也可以影响类路径下多种构建任务

2.1 compile

默认值, scope 声明为 compile 的依赖对项目所有类路径都可用,即对于编译、测试、运行三个状态都有效。此外,这样的依赖还可以在依赖它的项目中进行传递。

2.2 test

也是一个比较常用的取值,需要显式声明。最常见的使用 test 作为作用域的依赖就是 JUnit,它代表此依赖在正常使用时是不要求的(is not required for normal use of the application),例如:

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency>

被声明为 test 作用域的依赖,值针对test 代码,且无法进行依赖传递

2.3 provided

这个类型的 scope 和 compile 比较像。对于编译和测试有效,但运行时无效,典型的如servlet-api,运行时这个由容器来提供。简单的说,就是作用域为 provided 的依赖,可以参与 编译、测试等工作,相当于 compile 作用域,但是在打包的时候不需要打入包中,即在打包阶段做了 exclude 操作。此类型的依赖也是不能传递的

2.4 runtime

不太常用,对测试和运行有效,但编译无效。可以简单理解为对 provided 的一种互补。

2.5 system 

与provided的范围一样,但system必须显示的指定依赖文件,通过<systemPath>来进行指定,是与本机绑定的,所以基本很少用到。

2.6 import

这是唯一一个只能在 <dependencyManagement> 中使用的scope 类型。最常见的用法是引入 scope = import 的spring-boot-dependencies,这个依赖是连spring-boot-starter-parent都需要继承的父工程,用于进行诸多依赖版本的管理,使用方式是:

<dependencyManagement><dependencies><dependency><!-- Import dependency management from Spring Boot --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>1.5.2.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

 这些 scope 对编译、测试、运行可用的一览表:

scope编译测试运行
compileYYY
test Y 
providedYY 
runtime YY
systemYY 

三、作用域的传递性问题

scope 除了限制了依赖能够参与编译、测试、打包(运行)等工作外,还会对依赖的传递性有所影响,注意区分这两个知识点。

前面也已经提到,如果是默认的 compile 作用域,那么依赖会一直传递下去,不受任何影响,而 test 作用域的依赖,就无法进行依赖传递。

四、依赖的原则

在项目中,依赖往往遵循两个原则:

4.1 路径最短优先原则

当有同种依赖不同版本的时候,依照“路径最短者优先原则”。即默认使用层级关系最近的传递依赖。

4.2 先声明者优先原则

当路径距离相同时,根据“先声明者优先原则”来取舍。即dependency标签在上面的优先使用传递依赖。

如上图中 ,在 A 的pom 中如果 先声明了 C ,那么,将会优先使用 log4j.1.2.17版本。

五、依赖的排除

当我们不希望使用某些传递过来的依赖时可以使用这种方式,可能由于自动传递过来的此依赖版本不稳定,想替换成其他的依赖等等。

设置方式是在希望排除某个依赖的工程中配置<exclusions>标签即可。需要填写groupId和artifactId两项,那么不管什么版本的依赖都会被直接排除掉。另外,可以在层级视图中打开pom:

 

六、统一管理依赖版本

前面的文章中,介绍了通过父工程来管理子工程共同的一些依赖的版本号,然后在子工程中就不需要重复进行版本号的声明。

另外在一些只作用于当前pom 的版本号控制可以使用 <properties> 标签来声明,不仅仅是统一的版本号,项目编译、打包时的编码也可以进行指定。

 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决pom文件第一行报错(unknown)-亲测有效

原文链接&#xff1a;https://blog.csdn.net/u010947534/article/details/93743582 问题&#xff1a; Eclipse导入maven项目时&#xff0c;或者新建一个springboot项目时&#xff0c;pom.xml文件第一行报错&#xff0c;没有错误信息提示&#xff0c;就一个Unknown&#xff0c…

Oracle中start with xx connect by prior 语句解析

Oracle中start with xx connect by prior 语句解析 ​ Oracle这种的start with语句主要对B型树的数据进行递归查询.可以指定数据树上的任一节点,然后查找到它所有的子节点或者父节点. ​ 现在有如下图的数据: 我们先想数据库插入数据,这里用到oracle的批量插入写法# 1 建表 CRE…

Java NIO ———— Buffer 缓冲区详解

引言 缓冲区是一个用于特定基本类型的容器。由java.nio 包定义&#xff0c;所有缓冲区都是 Buffer 抽象类的子类。 Java NIO 中的 Buffer &#xff0c;主要用于与NIO 通道进行交互。数据从通道存入缓冲区&#xff0c;从缓冲区取出到通道中。 一、创建缓冲区 缓冲区的本质是 …

基本类型理解巩固及补码原理总结

引言 本篇文章属于计算机基础通识&#xff0c;主要讨论&#xff1a;有符号类型、无符号类型的区别&#xff0c;byte、int 等类型的取值范围&#xff0c;最大值最小值的计算公式的由来&#xff0c;原码、反码、补码转换公式。 有符号类型与无符号类型 在 Java 中的八大基本类…

LeetCode(#118)————杨辉三角形

问题描述 给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 示例: 输入: 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] ] 实现方法 class Solution {public List<List<Intege…

JVM001_类文件结构

无关性的基石 实现语言无关性的基础是虚拟机和字节码存储格式。Java虚拟机不与任何语言绑定&#xff08;包括Java&#xff09;&#xff0c;它只与‘Class文件’这种特定的二进制文件格式所关联。Class文件中包含了Java虚拟机指令集、符号表以及其它辅助信息。出于安全考虑&…

Maven学习(六)————企业Maven项目最佳实践

引言 在《Maven学习&#xff08;三&#xff09;————Maven核心概念&#xff08;二&#xff09;》中&#xff0c;学到了Maven 继承和 Maven 聚合的概念&#xff0c;这两个概念&#xff0c;解决的问题分别是&#xff1a; 1、解决一些公共依赖统一版本的问题。 2、统一打包部署…

JVM003_属性表

属性表 预备知识 javac -g Xxx.java 在生成class文件的时候生成所有调试信息javap -v Xxx.class 输出附加信息 属性表结构 类型名称数量备注u2attribute_name_index1属性名称索引&#xff0c;指向一个CONSTANT_Utf8_info型常量的索引u4attribute_length1该属性表的长度u1in…

Lombok ——自动化方法生成器

引言 此文为简单的Lombok 演示。 Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具&#xff0c;通过使用对应的注解&#xff0c;可以在编译源码的时候生成对应的方法。简而言之&#xff0c;一句话就是&#xff1a;通过简单的注解…

LeetCode(#26)————删除排序数组中的重复项

题目 给定一个排序数组&#xff0c;你需要在原地删除重复出现的元素&#xff0c;使得每个元素只出现一次&#xff0c;返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 示例 1: 给定数组 nums […

JVM006_类加载的过程

类加载 类加载时机 类加载的过程 新术语 类加载器 简单的理解为将类转换为二进制流的类或接口。 数组的元素类型 数组去掉所有维度的类型。 数组的组件类型 数组去掉一个维度的类型。 基本块 按照控制流拆分的代码块。 1. 加载 加载是类加载过程的一个阶段。加载阶段主…

服务端开发——云服务器的端口转发设置(SSH隧道)

引言 本篇博客介绍端口转发的知识&#xff0c;并详细阐述操作和设置步骤。这是因为在实际工作中&#xff0c;会有很多企业从安全的角度考虑&#xff0c;为线上或重要的服务器设置一个跳板机&#xff08;堡垒机&#xff09;&#xff0c;避免远程开发人员直接操作&#xff0c;是…

Shiro————核心设计思想

引言 以此篇博客为引&#xff0c;开启一个新的专栏分类——Shiro。 之前在工作中有比较快速的学习过Shiro安全框架&#xff0c;但经过一年的荒废&#xff0c;已经不是很熟悉了&#xff0c;通过这个系列&#xff0c;深入研究和学习Shiro的一些知识&#xff0c;填补安全管理方面…

Web应用安全————账号冻结与 Session 实时失效

引言 开篇时说些题外话&#xff0c;最近刚刚被公司CY&#xff0c;不过很快找到了下家&#xff0c;也同时拿到了三家公司的Offer。一周面试下来&#xff0c;总体感觉面试题少了&#xff0c;不过多了上机程序题。新公司是做外包&#xff0c;不过相比于上一家公司&#xff0c;也算…

Web应用安全————Shiro 解决会话固定漏洞

引言 承接上一篇《Web应用安全————账号冻结与 Session 实时失效》关于 session 的学习&#xff0c;本篇博客聚焦如何通过 shiro 解决会话固定导致的漏洞问题。 首先&#xff0c;没怎么接触过应用安全方面的小伙伴可能会发起疑问 - 什么是会话固定&#xff1f; 简单来说&…

Web应用安全————多点登录互斥

引言 在实际生活中&#xff0c;很多网站都做了多点登录互斥的操作&#xff0c;简单来说就是同一个账号&#xff0c;只能在一台电脑上登录&#xff0c;如果有人在其他地方登录&#xff0c;那么原来登录的地方就会自动下线&#xff0c;再进行操作就会弹出登录界面。 实现思路 …

Linux进阶之路————磁盘查询

引言 承接《Linux进阶之路————Linux磁盘分区与挂载》&#xff0c;本文介绍实际生产中对于磁盘的监控和查询。 一、查询磁盘整体使用情况 基本语法&#xff1a; df -h 该命令会显示包括我们手动挂载的磁盘&#xff0c;如果使用 umount 卸载磁盘&#xff0c;那么将不会显示…

Linux进阶之路————CentOS网络配置

引言 Linux在装机后&#xff0c;如果没有特殊配置&#xff0c;会使用动态获取 IP 地址的策略。本文描述了&#xff0c;虚拟机使用网络的拓扑图&#xff0c;以及如何通过配置&#xff0c;将 IP 地址固定下来&#xff0c;不会因为重启而失效。同时可以访问外网地址。 一、NAT模…

Linux进阶之路————进程与服务管理

引言 在Linux 中&#xff0c;每个执行的程序&#xff08;代码&#xff09;都成为一个进程&#xff0c;Linux 为每一个进程分配了一个唯一的 id 号 - PID。 每个进程都会对应一个父进程&#xff0c;而这个父进程可以复制多个子进程&#xff0c;例如 www 服务器。 每个进程都可…

Linux进阶之路———— RPM 与 YUM 包管理

引言 rpm 是一种用于互联网下载的打包及安装工具&#xff0c;它包含在某些 Linux 发行版中&#xff0c;生成具有 .rpm 扩展名的文件。rpm 是 redhat package manager&#xff08;RedHat 软件包管理器&#xff09;的缩写&#xff0c;类似 Windows 下的 setup.exe 文件。这一文件…