Maven(二)

Mvane的依赖范围

Maven 的依赖范围(Dependency Scope)用于精确控制依赖项在项目构建生命周期中的使用阶段和传递性,是避免依赖冲突和优化构建的关键配置。

Scope 是否参与编译 是否参与测试 是否打包 是否传递 典型应用场景
compile 核心依赖(如 Spring Core、Lombok)
provided 容器/运行时提供的依赖(如 Servlet API)
runtime 运行时需但编译不需的依赖(如 JDBC 驱动)
test 测试专用库(如 JUnit、Mockito)
system 本地系统路径的依赖(不推荐使用)
import - - - - 仅用于 <dependencyManagement>

其实也就是我们在引入依赖的时候可选的<scope>标签,在这里面填写依赖的范围如下:

复制代码
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
<!-- 就是这个--!>
    <scope>provided</scope>
</dependency>

其他的都还好理解,一般来说我们也不会去填写,高级的特性也就是最后一个improt这个范围,import 是 Maven 依赖范围中最特殊 的一种,它仅用于 <dependencyManagement> 部分,专门用来继承第三方项目的依赖管理配置(如 Spring Boot 或 Dubbo 的 POM 文件)。

特性 说明
唯一用途 仅在 <dependencyManagement> 中生效,用于导入第三方 POM 的依赖管理配置
非传统依赖范围 不参与编译、测试、打包,​仅做依赖版本管理
依赖传递性 无传递性(不会引入实际依赖)
典型应用场景 统一管理多模块项目或生态系统的依赖版本(如 Spring Cloud 版本对齐)

这个有什么作用呢?一般就是用来进行版本管理的,这个其实和继承有点类似,但是区别也是很明显的,因为导入只会导入<dependencyManagement> 中的内容,而且导入后还必须声明依赖不然这个依赖也不回被导入,就比如Bpom有个a依赖版本是1,Apom导入了Bpom,如果不在<dependencies>(Apom中<dependencyManagement>外的<dependencies>才行)中声明a依赖也是没有用的不会真正导入。如果声明了依赖没声明版本就会默认使用Bpom中的版本,如果声明了版本就会使用A的。

特性 继承 (<parent>)​ 导入 (<scope>import)​
语法 在 POM 中声明 <parent> <dependencyManagement> 中声明 import
继承内容 父 POM 的所有配置(依赖、插件、属性等) 仅合并目标 POM 的 <dependencyManagement>
多继承支持 ❌ 只能单继承 ✅ 可导入多个 BOM
依赖传递 父 POM 的普通 <dependencies> 会传递 仅版本管理,需显式声明依赖
插件配置 继承父 POM 的 <build> 配置 ❌ 不继承插件
适用场景 统一项目结构、共享插件/资源 集中管理依赖版本(如 Spring Boot BOM)
复制代码
<project>
    <dependencyManagement>
        <dependencies>
            <!-- 导入 B 的 dependencyManagement -->
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>B</artifactId>
                <version>1.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
#也可以在这里声明版本,这个声明的上下没关系,只要在Apom的dependencyManagement中声明了就不会使用Bpom的版本,当然还是要在外面声明依赖,不然依赖还是不会被引入
            <dependency>
            <groupId>com.example</groupId>
            <artifactId>a</artifactId>
            <version>1</version>
        </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 必须显式声明依赖才会引入 -->
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>a</artifactId>
            <!-- 版本从 B 继承 -->
        </dependency>
    </dependencies>
</project>

所以从这些看来,这个<dependencyManagement>标签只是用来统一管理版本的,其他的作用几乎没有用了,要注意的是<dependencyManagement>中定义的依赖的范围、排除、包含什么的标签也是会被导入到Apom的,反正记住只会导入<dependencyManagement>标签中的东西就对了。

Maven的依赖传递

我们上一篇已经说过了A依赖B依赖C这个C是怎么导入的,现在我们需要结合今天的依赖范围来重新认识一下,也就是不同的依赖范围会决定会不会引入C依赖,就比如B依赖的C使用的是provided范围,那么B是不会报错的,但是A使用B的时候如果用到了C那么就会报错,因为C并没有被传递进来。但是一般情况下大家使用的也是默认的依赖范围compile。

还有个最短路径优先的问题,在上面这个图中C 的 1.0 版本会被选中(路径更短),那如果两个路径一样长那么就会出现依赖冲突了,需要我们手动解决了,我们可以显示声明,也可以使用importPOM文件进行统一管理版本。

复制代码
#查看依赖树形结构
mvn dependency:tree

#分析依赖冲突
mvn dependency:tree -Dverbose

我们可以使用上面的命令来查看依赖的树形结构,以及通过命令来查看依赖的冲突。就像下面这样可以查看依赖的树形结构以及每个依赖的范围是怎么样的。分析依赖冲突的这边就不演示了,相比前者就是信息更加充分。

总结

本篇主要讲了Maven的依赖范围和传递关系。

相关推荐
liu****16 分钟前
4.基础开发工具(一)
linux·开发语言·1024程序员节
文火冰糖的硅基工坊16 分钟前
[人工智能-大模型-72]:模型层技术 - 模型训练六大步:①数据预处理 - 基本功能与对应的基本组成函数
开发语言·人工智能·python
小龙报21 分钟前
《C语言疑难点 --- 字符函数和字符串函数专题(上)》
c语言·开发语言·c++·算法·学习方法·业界资讯·visual studio
凭君语未可26 分钟前
深度解析Java的多态特性
java·开发语言
csbysj202037 分钟前
DTD 元素:XML 与 SGML 文档结构解析指南
开发语言
傻童:CPU1 小时前
C语言练习题
c语言·开发语言
华仔啊1 小时前
JVM参数到底配在哪?7大场景全解,新手不再迷茫!
java·jvm
极地星光1 小时前
协程:实战与系统集成(高级篇)
开发语言
0和1的舞者1 小时前
《Git:从入门到精通(八)——企业级git开发相关内容》
大数据·开发语言·git·搜索引擎·全文检索·软件工程·初学者
liulilittle2 小时前
LwIP协议栈MPA多进程架构
服务器·开发语言·网络·c++·架构·lwip·通信