当前位置: 首页 > news >正文

maven之scope

概览

在 Maven 中,scope 定义了依赖的可见性和生存周期,主要影响依赖在编译、测试和运行阶段的可用性,以及是否传递给下游模块。以下是 Maven 中常用的 scope 类型及其作用:


1. compile(默认范围)

  • 作用
    • 依赖在编译、测试和运行时都可用。
    • 是大多数依赖的默认范围,例如一些基础库(如日志框架、通用工具库等)。
  • 特点
    • 传递性:会传递到下游模块。
  • 典型场景
    • 引入需要在代码中直接使用的类库(如 Apache Commons、Guava 等)。

2. provided

  • 作用
    • 依赖在编译和测试阶段可用,但在运行时需要由运行环境提供。
  • 特点
    • 不传递到下游模块。
  • 典型场景
    • Servlet API、JSP API 等,通常由应用服务器(如 Tomcat、Jetty)提供。
  • 示例
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>

3. runtime

  • 作用
    • 依赖在测试和运行阶段可用,但编译阶段不可用。
  • 特点
    • 传递性:会传递到下游模块。
  • 典型场景
    • 依赖只在运行时需要,例如 JDBC 驱动。
  • 示例
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version><scope>runtime</scope>
</dependency>

4. test

  • 作用
    • 依赖只在测试阶段可用(编译和运行测试时)。
  • 特点
    • 不传递到下游模块。
  • 典型场景
    • 测试框架(如 JUnit、Mockito)。
  • 示例
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.3</version><scope>test</scope>
</dependency>

5. system

  • 作用
    • 类似于 provided,但需要显式提供依赖的 JAR 路径。
  • 特点
    • 不推荐使用,容易导致依赖路径硬编码。
    • 必须通过 systemPath 指定本地文件路径。
    • 不传递到下游模块。
  • 示例
<dependency><groupId>com.example</groupId><artifactId>example-lib</artifactId><version>1.0</version><scope>system</scope><systemPath>${project.basedir}/libs/example-lib.jar</systemPath>
</dependency>

6. import

  • 作用
    • 专用于 <dependencyManagement> 中,用于导入一个依赖的 BOM(Bill of Materials)。
  • 特点
    • 通常用于聚合模块或管理版本。
  • 示例
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>3.1.4</version><type>pom</type><scope>import</scope>
</dependency>

7. 总结对比

Scope编译测试运行传递性典型用途
compile✔️✔️✔️✔️通用依赖(默认)
provided✔️✔️由容器提供的依赖
runtime✔️✔️✔️JDBC 驱动等运行时依赖
test✔️单元测试框架
system✔️✔️✔️手动指定本地依赖(不推荐)
importN/ABOM 导入

通过合理设置 scope,可以优化依赖的管理和传递,避免冗余依赖影响构建效率和运行环境。

Q&A

如果我有一个common包被多个项目依赖,common中增加了一个依赖,但是想让引入common包的依赖方选择是否引入该新增的依赖,应该怎么选择scope?

如果你希望 common 包中新增的依赖由依赖方自行决定是否引入,通常的做法是将该依赖的 scope 设置为 **provided**。以下是具体原因和实现方式:


原因

  1. **provided**** 的特性**:
    • common 包中,这个依赖仅用于编译和测试阶段,但不会随着 common 包传递给下游模块。
    • 下游项目需要该功能时,可以显式添加这个依赖;不需要时,可以忽略。
  2. 保持依赖的灵活性
    • 使用 provided,你可以避免强制下游模块引入不需要的依赖,减少潜在的依赖冲突。

实现方式

commonpom.xml 中,将压缩依赖的 scope 设置为 provided

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.23.0</version><scope>provided</scope>
</dependency>

下游项目的选择

  • 需要该依赖的项目: 在项目的 pom.xml 中显式引入压缩依赖:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.23.0</version>
</dependency>
  • 不需要该依赖的项目: 不添加该依赖即可,provided 范围不会影响它们。

注意事项

  1. **optional**** 的对比**:
    • 另一种方案是将压缩依赖标记为 **optional**,这会阻止该依赖传递到下游模块,但依赖方仍可选择显式添加:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.23.0</version><optional>true</optional>
</dependency>
- 区别:* `optional` 适用于完全可选的功能。* `provided` 更适合运行环境提供依赖的场景,或你希望控制依赖的范围。
  1. 文档说明: 在 common 包的文档或 README 中,清楚说明压缩功能的依赖需求,避免依赖方困惑。
  2. 避免类路径问题: 如果 common 包中使用了压缩库的代码,但下游项目未引入该依赖,可能会出现 ClassNotFoundExceptionNoClassDefFoundError。务必提醒依赖方注意这一点。

相关文章:

  • 3DS中文游戏全集下载 任天堂3DS简介3DS第一方独占游戏推荐
  • 期货反向跟单-终止盘手合作原则(二)
  • 传输层协议UDP/TCP
  • 【Leetcode】字符串之二进制求和、字符串相乘
  • 数据结构-顺序表-数值统计
  • 设计模式之单例模式-----实现单例模式的五种方式
  • 多模态大语言模型arxiv论文略读(130)
  • 人力资源战略重构,AI驱动高质量发展论坛顺利召开
  • @annotation:Spring AOP 的“精准定位器“
  • Qt5.15.2 可执行程序发布
  • Rust 学习笔记:关于 Unsafe Rust 的练习题
  • Java八股文——消息队列「场景篇」
  • VSCode1.101.1Win多语言语言编辑器便携版安装教程
  • 【工具教程】识别PDF中文字内容,根据文字内容对PDF批量重命名,提取识别PDF内容给图片重新命名的操作步骤和注意事项
  • uniapp评价组件
  • 从生活场景学透 JavaScript 原型与原型链
  • 微信小程序扫码添加音频播放报错{errCode:10001, errMsg:“errCode:602,err:error,not found param“}
  • VR 看房:突破成长痛点,展望未来趋势
  • YOLOv5 自定义模型 Android 部署完整指南
  • C++11 右值引用(Rvalue Reference)
  • 建设自己的电影网站/免费网站制作软件平台
  • 网站制作及排名优化/手机网站
  • 徐汇区b2b"b2c行业门户网站开发_电子商业门户网站建设/友情链接交换的意义是什么
  • 基础型网站套餐/福州seo网站推广优化
  • 网站可以做多少个关键词/镇江网站建设
  • 网站建设选哪个/磁力岛