Maven的Scope标签详解

Maven的Scope标签详解

介绍

在 Maven 中,<scope> 标签用于定义依赖项的作用范围。作用范围确定了依赖项在项目构建过程中的可见性和可用性。

详情请查看官网对scope的介绍

使用场景

下面是 Maven 中 <scope> 标签的每个选项的含义和使用场景案例:

  • compile(默认值):这是最常用的作用范围。依赖项在编译、测试和运行时都是可见的。该依赖项将被包含在最终的构建产物(例如 JAR 文件)中,并且也会传递给依赖于当前项目的其他项目。
    案例:Spring context依赖。这个依赖在编译期和运行期都需要,所以使用默认的compile scope。

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
    </dependency>
  • provided:依赖项在编译和测试时是可见的,但在运行时由目标环境(例如应用服务器)提供。这意味着在构建过程中需要依赖项,但在部署到运行环境时不需要将其打包进最终的构建产物中。常见的示例是 Java EE 容器提供的 API,如 Servlet APIJSP API 等。
    案例:Servlet API依赖。这个依赖在编译和测试期需要,但运行期由web容器提供,所以使用provided scope。

    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
    </dependency> 
  • runtime:依赖项在运行时是可见的,但在编译和测试时不需要。这意味着在编译和测试代码时,不需要将其包含在类路径中,但在运行时需要。常见的使用场景是 JDBC 驱动程序,它只在应用程序运行时才需要。
    案例:JDBC驱动依赖。这个依赖只在运行和测试期需要,编译期不需要,所以使用runtime scope。

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId> 
    <version>8.0.15</version>
    <scope>runtime</scope>
    </dependency>
  • test:依赖项仅在测试代码的编译和运行时可见。这意味着它们不会被包含在最终的构建产物中,也不会传递给其他项目。这些依赖项通常是用于编写和执行单元测试、集成测试或功能测试的工具和框架。
    案例:JUnit依赖。这个依赖只在测试期需要,编译和运行期不需要,所以使用test scope。

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope> 
    </dependency>  
  • system(已废弃):这是一种特殊的作用范围,需要显式指定依赖项的路径。这意味着 Maven 不会在仓库中查找该依赖项,而是在本地系统中指定的路径查找。这种作用范围很少使用,并且容易导致构建的不可移植性,因为它依赖于本地系统的特定路径。
    案例:使用系统路径提供的依赖。需要显示提供systemPath来指向本地的jar文件。

    <dependency>
    <groupId>some-system-dependency</groupId>
    <artifactId>some-system-artifact</artifactId>
    <version>1.0.0</version> 
    <scope>system</scope>
    <systemPath>${basedir}/some.jar</systemPath>
    </dependency>
  • import(重要):该作用范围只能在 <dependencyManagement> 部分使用,用于导入其他 Maven 项目的依赖管理信息。它允许您引入其他项目的 <dependencyManagement> 部分,并将其作为当前项目的依赖管理信息。常用于引入外部POM文件来进行版本控制。
    案例:通过dependencyManagement导入的依赖。这个依赖仅起占位作用,不会实际调用,只是为了在多个模块中共享同一个版本。在父POM中:

    <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.5.6</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
    </dependencyManagement>

    在子模块中:

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    这里的import scoped依赖spring-boot-dependencies不会实际引入,只是为了在子模块中使用父POM中统一管理的版本。
    如果不使用import scope,子模块会试图实际调用这个依赖,这不是我们的初衷。所以,总结来说,import scope用于告知Maven:不需要实际调用这个依赖。只需要使用依赖管理中指定的版本号。

总结

这些作用范围选项在 Maven 中的作用是为了控制依赖项在不同环境下的可见性和传递性。选择适当的作用范围可以减少构建产物的大小,优化构建过程,并确保依赖项的正确使用和管理。

参考

Maven官网对scope的介绍

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注