在 Maven 中,<scope>
定义了依赖的可见性和生命周期。不同的 scope
值指示 Maven 在编译、测试和运行时如何处理这些依赖。以下是 Maven 中的几种常用依赖范围及其详细说明:
1. <scope>provided</scope>
- 含义:
provided
范围表示该依赖在编译时可用,但在运行时并不需要包含在最终的构建产物(如 JAR 或 WAR 文件)中。 - 使用场景:
- 该依赖通常由运行环境提供,例如应用服务器(如 Tomcat、Jetty)会提供 Servlet API 和 JSP API。
- 特点:
- 编译时可用,但打包时不会被包含。
- 在 WAR 文件中,依赖的库已经由应用服务器提供。
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>
2. <scope>compile</scope>
- 含义:
compile
是默认的范围,表示该依赖在所有阶段(编译、测试、运行)都可用。 - 使用场景:
- 常用于项目中的核心库和功能,例如第三方库或框架。
- 特点:
- 既可以在编译时使用,也可以在测试和运行时使用。
- 包含在最终构建产物中。
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version>
</dependency>
3. <scope>runtime</scope>
- 含义:
runtime
范围表示该依赖在运行时可用,但在编译时不可用。 - 使用场景:
- 通常用于那些编译时不需要、但在运行时需要的库,比如 JDBC 驱动程序。
- 特点:
- 不会在编译时加入类路径,但在执行时需要存在。
- 包含在最终构建产物中。
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version><scope>runtime</scope>
</dependency>
4. <scope>test</scope>
- 含义:
test
范围表示该依赖仅在测试时可用,不会在编译或运行时包含在内。 - 使用场景:
- 用于测试框架和工具,如 JUnit、Mockito 等。
- 特点:
- 只在单元测试和集成测试中使用。
- 不包含在最终构建产物中。
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>
5. <scope>system</scope>
- 含义:
system
范围用于指定系统范围的依赖,通常需要手动指定依赖的路径。 - 使用场景:
- 适用于那些不能从 Maven 仓库获取的 JAR 文件,通常是本地文件或者不在中央仓库的库。
- 特点:
- 需要提供
systemPath
来明确指定该依赖的路径。 - 不应该经常使用,因为直接依赖于文件系统可能会破坏构建的可移植性。
- 不应与 Maven 的仓库系统配合使用。
- 需要提供
<dependency><groupId>com.example</groupId><artifactId>my-local-library</artifactId><version>1.0</version><scope>system</scope><systemPath>${project.basedir}/libs/my-local-library.jar</systemPath>
</dependency>
总结
provided
: 编译时可用,运行时由环境提供,不包含在构建产物中。compile
: 默认范围,编译、测试、运行时均可用,包含在构建产物中。runtime
: 编译时不可用,仅在运行时可用,包含在构建产物中。test
: 仅在测试时可用,不包含在构建产物中。system
: 手动指定路径的依赖,直接依赖本地文件,通常不推荐使用。