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

理解 Maven 依赖范围及编译与运行时的需求

在使用 Maven 构建 Java 项目时,我们经常需要添加各种依赖(JAR 包)到项目中。然而,依赖的作用范围(Scope)决定了这些 JAR 包在不同阶段的作用和存在方式。本文将详细介绍 Maven 依赖范围的定义、编译和运行时的需求,以及如何正确理解这些概念。

Maven 依赖范围(Scope)

在 Maven 的 pom.xml 文件中,依赖的 scope 元素用来定义该依赖的作用范围。常见的作用范围包括:

  1. compile:默认范围。编译、测试、运行和打包时都需要这个依赖。适用于所有阶段。
  2. provided:编译和测试时需要,但在运行时由外部环境提供。适用于如 Servlet API 这样的库,通常由容器(如 Tomcat)提供。
  3. runtime: 编译时不需要,但在运行时需要。适用于 JDBC 驱动程序等库。
  4. test:只在测试阶段需要,不会包含在最终的构建包中。适用于 JUnit 等测试框架。
  5. system:与 provided 类似,但需要在本地文件系统中指定路径,通常不推荐使用。

编译时与运行时的 JAR 包需求

1. 编译时的依赖

编译时,Java 编译器需要知道你代码中所使用的类和接口的定义。如果你在代码中引用了某些类,编译器需要能够找到这些类的定义文件。例如:

  • HttpServletRequestHttpServletResponse:这些类属于 Servlet API。为了编译使用这些类的代码,编译器需要知道这些类的定义。为了达到这个目的,你必须在 pom.xml 文件中将 Servlet API 的依赖 scope 设置为 provided,因为 Servlet API 是由应用服务器(如 Tomcat)提供的。

    <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
    </dependency>
    
  • 编译期依赖的例子:假设你在项目中使用了 HttpServletRequest,编译时需要 javax.servlet-api JAR 包,因为编译器需要知道 HttpServletRequest 类的定义。

2. 运行时的依赖

在代码编译完成后,应用程序在运行时需要不同的依赖来完成实际的操作。运行时依赖是指那些编译时不需要,但在应用程序运行时必须存在的 JAR 包。例如:

  • JDBC 驱动程序:编写数据库操作代码时,使用 JDBC 接口来访问数据库,而不是具体的 JDBC 实现(如 MySQL JDBC 驱动)。因此,编译时不需要 MySQL 驱动程序,但在运行时需要它来实际连接 MySQL 数据库。你需要在 pom.xml 文件中将 JDBC 驱动程序的 scope 设置为 runtime

    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version><scope>runtime</scope>
    </dependency>
    
  • 运行期依赖的例子:在运行时,JVM 需要 MySQL JDBC 驱动来连接数据库。虽然在编译时只需要 JDBC 接口,但运行时需要实际的 JDBC 驱动程序。

编译和运行时的具体示例

示例 1: Servlet API

在编写和编译 Java Servlet 时,必须使用 Servlet API 的类,如 HttpServletRequestHttpServletResponse。这些类的定义由 Servlet API 提供,这意味着在编译阶段,你需要将 Servlet API 的 JAR 包包含在项目中,但实际的 Servlet 容器(如 Tomcat)会在运行时提供这些 API 的实现。

示例 2: JDBC 驱动

假设你的项目使用 JDBC 连接 MySQL 数据库。编写代码时,你使用的是 JDBC 接口(如 ConnectionDriverManager),这些接口由 Java 标准库提供。编译时,编译器不需要 MySQL 驱动程序。只有在实际运行时,JVM 需要 MySQL JDBC 驱动程序来建立数据库连接。

不太明白的同学可以到这里看看----->代码实例

总结

理解 Maven 依赖的范围及其对编译和运行时的需求,对于有效管理项目依赖非常重要。编译时需要的依赖确保你的代码可以顺利编译,而运行时依赖则确保你的应用在实际运行时可以正常工作。通过合理设置依赖的 scope,可以优化项目的构建和运行环境。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C#文件的输入和输出
  • 产品入门篇笔记
  • 2024年国家自然科学基金即将公布,如何第一时间知道评审结果?
  • priority_queue的使用方法
  • 树状数组C/C++实现
  • 解决 JS WebSocket 心跳检测 重连
  • Hive出现BigDecimal wourld overflow supported range问题
  • Codeforces Round 964 (Div. 4) A-E Java题解
  • 告别无序 10款科研项目管理工具为您的科研之路加速
  • 【战术无线电通信】数据链
  • TinyTNAS: 不依赖GPU的、有时间限制的、硬件感知的神经架构搜索,用于TinyML时间序列分类
  • TypeScript与vue
  • 【Matlab】时间序列模型(ARIMA)
  • sql 4,创建表类型
  • 波导阵列天线单元学习笔记7 一种用直接金属激光烧结考虑的轻质量,宽带,双圆极化波导腔体阵列
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 〔开发系列〕一次关于小程序开发的深度总结
  • hadoop集群管理系统搭建规划说明
  • JavaScript 奇技淫巧
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JAVA之继承和多态
  • k8s如何管理Pod
  • mockjs让前端开发独立于后端
  • MySQL用户中的%到底包不包括localhost?
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Python中eval与exec的使用及区别
  • Sequelize 中文文档 v4 - Getting started - 入门
  • Swoft 源码剖析 - 代码自动更新机制
  • vue-router 实现分析
  • 记一次和乔布斯合作最难忘的经历
  • 配置 PM2 实现代码自动发布
  • 为什么要用IPython/Jupyter?
  • 小程序开发中的那些坑
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 如何用纯 CSS 创作一个货车 loader
  • ​io --- 处理流的核心工具​
  • #define、const、typedef的差别
  • #if 1...#endif
  • #pragma data_seg 共享数据区(转)
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (06)Hive——正则表达式
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (void) (_x == _y)的作用
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (函数)颠倒字符串顺序(C语言)
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (六)DockerCompose安装与配置
  • (十三)Flink SQL
  • (循环依赖问题)学习spring的第九天
  • (转)【Hibernate总结系列】使用举例
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (状压dp)uva 10817 Headmaster's Headache