您的位置:

scopeprovided解析:探究依赖管理中scopeprovided的应用场景

一、scopeprovided概述

在Maven的依赖管理范畴中,scopeprovided代表依赖关系的一种“范畴”,与被依赖项目的编译构建不带来实际用处的依赖关系,通常以optional或provided为属性。

换句话说,scopeprovided设定的依赖关系只在编译期和测试期中生效,并在运行时被丢弃。这意味着,该依赖项只在项目的编译和测试中有效。

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
   </dependency>
</dependencies>

在上面的代码例子中,与servlet-api相关联的依赖项的作用仅限于编译和测试,在运行时不会被打包。如果用户所在的容器已经包含了servlet-api的库,就不必将它打包进war文件中,因此该依赖此时可用于编译,但不用于部署。

二、scopeprovided的使用场景

1.与Java标准库相关的依赖库

与应用程序运行环境相关的库,比如Java标准库,即使没有将其作为Maven依赖项导入,Java运行时环境也将它们提供给应用程序。

例如,如果我们想要为servlet应用程序设置ContextPath,则只需要导入web.xml文件就可以了,这样就可以通过web服务器运行和测试应用程序。在这种情况下,servlet-api与Java标准库相关,因此我们可以将其声明为provided,而不必将其打包到生产环境中:

<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
</dependency>

2.减少部署时的依赖项

当项目打算部署时,我们通常会将其从测试环境中移植到生产环境中。在此过程中,需要将我们已经编译过的代码移植到生产环境,并将所有依赖库(除Java标准库之外)放在一个classpath中。一般来说,同样的依赖包会被多个依赖库中所使用,无需重复下载或者打包到多个部署包中。因此为了提高效率,最好将所有这些依赖项打包在一个单独的文件中,让所有应用程序都可以共享它们而不用重复下载。

这就是scopeprovided的另一个用例:它能帮助我们仅将必须部署的依赖项打包到生产环境中,而不会重复打包在它们依赖的多个模块中。我们可以使用该范畴来告诉Maven,一些依赖仅在JAR打包时有效,而不是在WAR或EAR打包时有效。

3.与插件相关的范畴

Maven插件是Maven生态系统中非常重要的一部分,Maven插件通常也会有自己的宿主环境(如Jetty或Tomcat)。在某些情况下,插件可能需要一些额外的依赖项来执行其任务。为了提供这些支持,将这些插件的依赖项声明为插件的scopeprovided是有意义的,因为它将允许这些依赖项在插件代码运行时被查找到,但不会被打包进用户项目中。

<plugins>
    <plugin>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-maven-plugin</artifactId>
                        <version>9.4.31.v20200723</version>
<dependencies>
      <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.1.0</version>
           <scope>provided</scope>
      </dependency>
   </dependencies>
</plugin>
</plugins>

三、范畴unused的缺陷

相对于范畴provided的优点, unused的范畴不仅编译时用不到,并且test范畴通常代表着较大的测试代码,而且通常不需要在运行时打包。因此,它的适用范围通常更小。

然而,unused范畴的一个缺陷是无法自动删除所有未使用的依赖项,一些用户仍然有一些未删除的垃圾文件,这会使项目变得丑陋,难以维护。

结论

范畴provided是作为Maven支持库中最常用的范畴之一。在依赖管理中,scopeprovided 常见的使用场景是:与Java标准库相关的依赖库、减少部署时的依赖项、与插件相关的范畴。unused的范畴与之相比,它的使用范围通常更小,且不能自动删除未使用的依赖项,将文件留下来会使项目难以维护,变得丑陋。