前言

在Intellij IDEA的Run/Debug Configurations配置页面,有一个可选参数:Include dependencies with "Provided" scope,在第一次下载调试代码时,同事提醒我需要勾选,当时并不清楚这个配置项的含义。现在对Maven的了解更深入了一点,了解到这个配置项和Maven的Dependency.scope参数有关。

正文

Maven的生命周期存在编译、测试、运行这些过程。有些依赖只需要用于测试,比如Junit;有些依赖编译的时候用不到,在运行的时候才能用到,比如数据库驱动包(编译时用的是JDBC接口,运行时才需要数据库驱动);还有些依赖在编译时要用到,在运行时不需要提供,因为有些容器已经提供了,比如servlet-api在tomcat中提供了,因此我们只需要在编译期提供。

因此,POM4引入了scope,可以用来管理依赖的部署,scope支持如下配置:

  1. compile:

compile是默认的scope参数,不配置就意味着compile,配置为compile的依赖需要参与当前项目的编译、测试、运行和打包,是一个比较强的依赖。

  1. runtime:

    配置为runtime的依赖无须参加当前项目的编译,但是需要参与当前项目的测试、运行和打包,等于和compile相比跳过了编译。

  2. test:

配置为test的依赖在编译、运行和打包时都不需要,它们只在测试编译和测试运行阶段可用。

  1. provided:

配置为provided的依赖在编译、运行和测试阶段起作用,但是打包时不会打包进去。目前我看到了两种使用场景,一种是像servlet-api依赖,由容器提供;一种是像log依赖,不依赖具体实现,只依赖日志框架。

  1. system:

配置的system的依赖性不会从maven仓库中下载,而是往本地系统执行路径下查找,需要配置systemPath属性,使用的比较少。指定systemPath有多种方法,可以参考:链接

scope的依赖传递,当A依赖于B,B依赖于C时,怎么确定C在A中的scope?

  1. A是否依赖C由C在B中的scope决定,如果C在B中的scope是test或者provided,C直接被丢弃,A不依赖C。
  2. 否则,C在A中的scope继承自B在A中的scope。