Maven dependency的scope作用域

本文深入解析Maven中六种依赖范围(compile、provided、runtime、test、system、import)的作用与应用场景,结合项目实例帮助理解如何正确配置依赖,避免版本冲突,减少包体积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

maven官网对于scope的6种类型解释的较简洁,并不能让人很好理解。在此进行翻译并结合项目经历做进一步拓展解释。
以下摘自maven官网:
在这里插入图片描述

  • compile
    maven默认的scope如果<dependency>未显式声明<scope>,则默认使用compile,当前项目中所有模块都可直接引用被修饰的jar包。并且可以以传递依赖的方式被其他项目直接引用。

  • provided
    provided修饰的jar包并不会直接打包到项目lib目录中,仅保证项目编译和测试的classpath中的文件在引用该jar包时不会报错。保证项目运行时正常。适用场景:承载项目的容器默认提供了该jar包,例如:java web项目需要使用相关servlet-api.jar,需要在pom中显式声明该jar,但是web容器例如:tomcat,提供该jar包支持。故无需在打包时将jar打包进来。另引用的父项目下有可能也声明了同类jar,在打包时设置<scope>provided</scope>可以排除引用该jar包因为版本问题导致的冲突和错误,减少包的大小。

通过provided修饰的jar包,在ide中通过main方法执行时,引用相关方法,会报class not found的运行时异常。但是能正常打包,编译器编译检测也能通过,打出的包在容器中运行,如果容器提供相应包,程序将正常执行。项目启动时,使用java -Dloader.path=libs(文件夹) -jar指定依赖的引用路径。

  • runtime
    被修饰的jar包在编译时和打包时并不会被引用,打包的lib目录不会存在该jar包,只在运行时和测试时进行使用

  • test
    被修饰的jar只在测试编译和执行阶段使用,不会在项目正常运行时和编译的时候使用。

  • system
    与provided一样,被修饰的jar包并不会被打包到lib目录中,而是在运行时和编译时从特定的目录中去引用,而不是从maven的仓库中引用。需要同<systemPath>一起使用,指定依赖jar包的目录。

注:<systemPath>标签仅能与scope为system的属性一起使用,并且指定的路径为绝对路径。后续可能会被替代:
在这里插入图片描述

  • import
    仅可在<dependencyManagement>标签中使用。等价于<parent>。项目中往往会有自定义的<parent>引用,对于框架的引用,例如spring-boot,可放在<dependencyManagement>标签中使用。例如:
<dependencyManagement>
		<dependencies>
			<dependency>
				<!-- Import dependency management from Spring Boot -->
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>1.5.8.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

等价于

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.8.RELEASE</version>
	</parent>
### Maven依赖的作用域及其用法 Maven中的依赖作用域Dependency Scope)用于定义项目中依赖的使用范围和生命周期。以下是常见的Maven依赖作用域及其解释: 1. **compile** 默认的作用域,适用于主代码和测试代码编译阶段。此作用域的依赖会被包含在项目的打包输出中,并且会传递给其他依赖该项目的模块[^4]。 2. **provided** 表示依赖在编译时需要,但在运行时由容器或JVM提供(例如Servlet API)。这种依赖不会被打包到最终的输出文件中[^5]。 3. **runtime** 依赖在运行时需要,但编译时不需要直接引用(例如JDBC驱动程序)。此作用域的依赖不会影响编译过程,但会在运行时加载[^6]。 4. **test** 仅在测试编译和执行阶段有效(例如JUnit)。此作用域的依赖不会被传递到主代码或其他模块中[^7]。 5. **system** 类似于`provided`,但需要显式指定依赖的路径。由于这种方式不推荐使用(因为它破坏了Maven的可移植性),通常避免使用此作用域[^8]。 6. **import** 专门用于导入其他POM文件中的依赖管理部分,常用于BOM(Bill of Materials)模式[^9]。 以下是一个示例,展示如何在`pom.xml`中配置不同作用域的依赖: ```xml <dependencies> <!-- 编译时和运行时都需要 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.10</version> <scope>compile</scope> </dependency> <!-- 运行时需要,编译时不直接引用 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> <scope>runtime</scope> </dependency> <!-- 测试时需要 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <!-- 提供者负责提供 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> ``` 通过合理配置依赖的作用域,可以优化项目的构建过程,减少不必要的依赖传递,同时确保运行时所需的库正确加载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值