Maven依赖范围
Maven依赖范围
- 1 依赖范围
- 1.1 各阶段依赖可见性矩阵
- 1.2 作用范围矩阵
- 2 六大依赖范围全解析
- 2.1 compile:全生命周期依赖(默认范围)
- 2.2 test:测试阶段专属依赖
- 2.3 provided:运行时环境提供
- 2.4 runtime:运行时必需依赖
- 2.5 system:系统级依赖(谨慎使用)
- 2.6 import:依赖管理导入(仅限 dependencyManagement)
- 3 依赖传递与范围合并规则
- 3.1 传递依赖的范围计算逻辑
1 依赖范围
Maven依赖范围(Scope)用于控制依赖在不同构建阶段(编译、测试、运行)和类路径中的可用性,主要包括compile(默认)、provided、runtime、test、system和import六种类型。
1.1 各阶段依赖可见性矩阵
范围 | 编译阶段 | 测试阶段 | 运行阶段/打包阶段 |
---|---|---|---|
compile | ✅ | ✅ | ✅ |
test | ✅ | ✅ | ❌ |
provided | ✅ | ✅ | ❌ |
runtime | ❌ | ✅ | ✅ |
system | ✅ | ✅ | ✅ |
1.2 作用范围矩阵
- 主代码范围有效(main文件夹范围内)
- 测试代码范围有效(test文件夹范围内)
- 是否参与打包(package指令范围内)
范围 | 主代码 | 测试代码 | 打包 |
---|---|---|---|
compile | ✅ | ✅ | ✅ |
test | ❌ | ✅ | ❌ |
provided | ✅ | ✅ | ❌ |
runtime | ❌ | ❌ | ✅ |
2 六大依赖范围全解析
2.1 compile:全生命周期依赖(默认范围)
- 特性:
- 作用于编译、测试、运行全阶段,打包时包含在构建产物中
- 若 A 依赖 B(compile),则 B 对依赖 A 的项目可见
- 未声明 scope 时的默认值
- 代码示例:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.39</version><!-- 省略<scope>compile</scope>,默认生效 -->
</dependency>
2.2 test:测试阶段专属依赖
- 特性:
- 仅在测试编译、测试执行阶段有效
- 打包时不包含在最终产物中
- 典型应用于单元测试、集成测试框架
- 代码示例:
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>
- 典型应用场景:
- 测试模拟工具(Mockito、EasyMock)
- 测试数据生成库(Faker)
- 性能测试框架(JMeter API
2.3 provided:运行时环境提供
- 特性:
- 编译 / 测试阶段有效,但运行时由容器或 JDK 提供
- 打包时不包含(如 war 包部署时,servlet-api 由 Tomcat 提供)
- 避免依赖冲突(如多模块引入不同版本)
代码示例:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.7.16</version><scope>provide</scope>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.7.16</version><scope>compile</scope><optional>true</optional>
</dependency>
- 典型应用场景:
如spring-boot-autoconfigure 工程在自动配置redis的类,需要引入spring-boot-starter-data-redis,但是打包时又不能相应的jar打入package,就可以使用 provided
上述情况 通过 <optional>true</optional> 也可以实现
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;/**
@AutoConfiguration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
2.4 runtime:运行时必需依赖
- 特性:
- 编译阶段不需要,但运行时必须存在
- 比 compile 更轻量,减少编译时依赖污染
- 常见于数据库驱动、动态代理库
- 应用示例:
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version><scope>runtime</scope>
</dependency>
- 应用场景::
- JDBC 驱动(编译时无需加载,运行时才需要)
- 动态语言引擎(如 Java 11 的 Nashorn)
- 日志实现库(如 logback-classic)
2.5 system:系统级依赖(谨慎使用)
- 特性:
- 依赖于本地文件系统的特定路径
- 需显式指定systemPath,脱离 Maven 仓库管理
- 破坏项目可移植性,仅作为最后手段
– 示例:
<dependency><groupId>com.example</groupId><artifactId>local-lib</artifactId><version>1.0</version><scope>system</scope><systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
- 警告:
- 违背 Maven 依赖管理原则,可能导致构建环境不一致
- 推荐替代方案:将本地库部署到私服或使用 docker 封装
2.6 import:依赖管理导入(仅限 dependencyManagement)
将目标POM中的dependencyManegement配置导入合并到当前POM的dependencyManagement元素中。
例如,如果想要在另外一个模块中使用project-parent中配置的depemdencyManagement信息,除了复制配置或者继承这两者方式之外,还可以使用import范围依赖将这一配置导入
- 特性:
- 仅在dependencyManagement中使用
- 用于合并多个 pom 的依赖配置
- 不影响依赖传递,仅作版本管理
- 示例:
<dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.7.10</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
- 场景价值:
- 统一管理多模块项目的依赖版本
- 导入父项目或平台的依赖配置
- 简化子模块的依赖声明
3 依赖传递与范围合并规则
3.1 传递依赖的范围计算逻辑
当 A 依赖 B,B 依赖 C 时,C 对 A 的可见性遵循以下规则:
||||
A 的范围 | B 的范围 | C 对 A 的最终范围 |
---|---|---|
compile | compile | compile |
compile | test | test |
compile | provided | provided |
compile | runtime | runtime |
test | compile | test |
test | test | test |
test | provided | provided |
test | runtime | runtime |