Maven 依赖作用域详解:compile、provided、runtime、test

在 Maven 项目中,所有依赖通常都在 pom.xml 中通过 dependency 声明。但并不是所有依赖在项目生命周期的各个阶段都需要使用。例如,有些依赖只在 编译阶段 使用,有些只在 运行阶段 使用,还有一些只在 测试阶段使用。

为了解决这一问题,Maven 提供了 依赖作用域(Dependency Scope) 机制。
scope 用于定义依赖在 编译、运行、测试和打包阶段是否生效 ,从而决定该依赖是否会被加入到对应阶段的 类路径(classpath) 中。如果不显式指定 scope,默认值为:

一、Maven 的依赖管理机制

在 Maven 项目中,所有依赖都通过 pom.xml 文件声明,例如:

复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.0.0</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

如果不显式指定 scope,默认值为:

复制代码
compile

当 Maven 构建项目时,会自动完成以下工作:

  1. 读取 pom.xml 中定义的依赖

  2. 从远程仓库下载依赖

  3. 将依赖缓存到本地仓库

本地仓库位置:

复制代码
~/.m2/repository

随后 Maven 会在 不同构建阶段 将这些依赖加入不同的类路径中。

二、什么是类路径(Classpath)

在 Java 中,类路径(Classpath) 是 JVM 或 Java 编译器用于查找 .class 文件和依赖库的位置集合。

简单来说:

类路径就是 Java 程序在运行或编译时,用来查找类文件的路径列表。

类路径通常包含以下几种资源:

  • 项目编译后的 .class 文件

  • 第三方依赖库(jar)

  • 项目资源文件(resources)

如果某个类不在类路径中,程序就会出现典型错误:

复制代码
ClassNotFoundException
NoClassDefFoundError

而 Maven 的核心作用之一,就是 自动管理这些类路径依赖

三、Maven 常见的五种 scope

Maven 常见的依赖作用域主要包括以下几种。

1 compile(默认作用域)

compile 是 Maven 的 默认作用域 ,如果不写 scope,依赖默认就是 compile

特点:

  • 编译阶段可用

  • 运行阶段可用

  • 测试阶段可用

  • 打包时会被包含

例如:

复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
</dependency>

Spring 框架依赖通常就是 compile

适用于:

  • 项目核心依赖

  • 应用运行必须依赖的库

2 provided

provided 表示 编译时需要,但运行时由外部环境提供

特点:

  • 编译阶段可用

  • 运行阶段不可用

  • 不会被打包

典型例子:

复制代码
Servlet API

例如:

复制代码
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <scope>provided</scope>
</dependency>

原因是:

复制代码
Tomcat / Jetty 已经提供 Servlet API

如果再打包进去就会冲突。

3 runtime

runtime 表示 编译时不需要,但运行时需要

特点:

  • 编译阶段不可用

  • 运行阶段可用

  • 会被打包

典型例子:

复制代码
JDBC驱动

例如:

复制代码
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

原因:

编译代码只依赖:

复制代码
java.sql

但运行数据库时需要:

复制代码
java.sql

4 test

test 作用域只在 测试阶段生效

特点:

  • 编译主代码不可用

  • 运行主程序不可用

  • 仅在测试代码中可用

例如:

复制代码
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>

适用于:

复制代码
JUnit
Mockito
TestNG

这些库只在测试时使用。

5 system

system 依赖是 Maven 早期提供的一种方式,用于 引用本地 jar 包

例如:

复制代码
<dependency>
    <groupId>example</groupId>
    <artifactId>example-lib</artifactId>
    <scope>system</scope>
    <systemPath>D:/libs/example.jar</systemPath>
</dependency>

缺点:

  • 不参与 Maven 依赖管理

  • 不可移植

因此 基本不推荐使用

四、Maven scope 与类路径关系

Maven 在构建项目时,会根据 scope 决定依赖是否加入不同阶段的 classpath

scope 编译 运行 测试 打包
compile
provided
runtime
test

因此可以这样理解:

Maven 会根据 pom.xml 中依赖的 scope,在 编译、运行和打包阶段构建不同的 classpath,从而决定哪些依赖在不同阶段被引入。

相关推荐
QH_ShareHub2 小时前
Rstudio 与 R 打开 Rdata (压缩文件) 差异
java·前端·r语言
spencer_tseng2 小时前
apache-maven-3.9.6
java·maven
yashuk2 小时前
springboot与springcloud对应版本
java·spring boot·spring cloud
strayCat232552 小时前
4. Spring Boot 数据持久化(JPA)
java·spring boot·后端
无风听海2 小时前
LangGraph Thread 数据清理总结
java·开发语言·jvm·langchain·deep agents
strayCat232552 小时前
2. Spring Boot 自动配置原理深度解析
java·spring boot·后端
SimonKing2 小时前
每月500 Credits+不限频对话,这款IDEA插件的免费版诚意拉满
java·后端·程序员
星如雨グッ!(๑•̀ㅂ•́)و✧2 小时前
Webflux结合cassandra
java·开发语言
戴西软件2 小时前
乘用车车门结构侧面碰撞仿真全流程:PreSys + Ansys 实战操作
java·开发语言·python·ui·cae