天天看点

详解Maven中的Scope: Compile/Runtime/Provided都有什么区别?

作者:Mylovemusic

Maven是一个广泛应用的Java项目构建和依赖管理工具。在Maven中,Scope(作用域)用于控制依赖项在不同构建阶段的可见性和使用方式。本文将介绍Maven中最常用的5个Scope,包括其原理、应用场景,并通过实际例子说明每个Scope的用法。最后,我们将以表格形式展示这些Scope之间的区别。

Scope列表:

以下是Maven中最常用的5个Scope及其解释:

Scope 解释 应用场景
compile 默认Scope,依赖在所有构建阶段(编译、测试、运行)都可见和使用 主要用于项目的编译、测试和运行阶段
provided 依赖在编译和测试阶段可见,但在运行和打包阶段由目标环境(例如JDK或应用服务器)提供 主要用于项目在部署和运行阶段不需要打包的依赖,因为目标环境已经提供
runtime 依赖在运行和打包阶段可见和使用,但在编译和测试阶段不可见 主要用于项目在运行时需要,但在编译和测试时不需要的依赖
test 依赖仅在测试阶段可见和使用 主要用于项目的单元测试和集成测试
system 类似于provided Scope,但需要通过systemPath属性指定依赖项的路径 主要用于引入本地系统中的JAR文件或依赖项

实例:不同Scope的应用

接下来,我们将通过实际例子来说明每个Scope的用法。

  1. compile Scope:
<dependencies>
    <!-- 其他依赖项 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
        <scope>compile</scope>
    </dependency>
    <!-- 其他依赖项 -->
</dependencies>           

在上述示例中,commons-lang3依赖项的Scope设置为compile。这意味着该依赖在项目的编译、测试和运行阶段都可见和使用。

  1. provided Scope:
<dependencies>
    <!-- 其他依赖项 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- 其他依赖项 -->
</dependencies>           

在上述示例中,servlet-api依赖项的Scope设置为provided。这意味着在编译和测试阶段,servlet-api依赖在类路径中可见,但在打包和部署到应用服务器时,应用服务器会提供servlet-api,因此不需要将其打包到应用程序中。

  1. runtime Scope:
<dependencies>
    <!-- 其他依赖项 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
        <scope>runtime</scope>
    </dependency>
    <!-- 其他依赖项 -->
</dependencies>           

在上述示例中,mysql-connector-java依赖项的Scope设置为runtime。这意味着在编译和测试阶段不会将其添加到类路径中,但在运行和打包阶段中可见和使用。

  1. test Scope:
<dependencies>
    <!-- 其他依赖项 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <!-- 其他依赖项 -->
</dependencies>           

在上述示例中,junit依赖项的Scope设置为test。这意味着该依赖仅在项目的测试阶段可见和使用,而不会包含在最终的构建结果中。

  1. system Scope:
<dependencies>
    <!-- 其他依赖项 -->
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>custom-library</artifactId>
        <version>1.0.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/custom-library.jar</systemPath>
    </dependency>
    <!-- 其他依赖项 -->
</dependencies>           

在上述示例中,custom-library依赖项的Scope设置为system。通过systemPath属性,我们指定了依赖项的路径。这意味着该依赖项从本地系统中引入,而不是从Maven仓库中获取。

区别对比:

下表展示了这些Scope之间的区别:

Scope 编译阶段 测试阶段 运行阶段 打包阶段
compile 可见 可见 可见 可见
provided 可见 可见 不可见 不可见
runtime 不可见 不可见 可见 可见
test 不可见 可见 不可见 不可见
system 可见 可见 可见 可见

结论:Maven中的Scope用于控制依赖项在不同构建阶段的可见性和使用方式。本文介绍了Maven中最常用的5个Scope,并通过实际例子说明了每个Scope的应用场景和用法。表格形式的区别对比帮助我们更好地理解这些Scope之间的差异。通过正确选择和配置Scope,我们可以更好地管理项目的依赖关系,提高构建过程的灵活性和可维护性。

希望本文对于您理解和应用Maven中的Scope有所帮助。通过灵活使用这些Scope,您可以更好地管理和控制项目的依赖项,提高开发效率和软件质量。

摘自:科学随想录