maven官网对于scope的6种类型解释的较简洁,并不能让人很好理解。在此进行翻译并结合项目经历做进一步拓展解释。
以下摘自maven官网:
- compile
maven默认的scope如果<dependency>
未显式声明<scope>
,则默认使用compile,当前项目中所有模块都可直接引用被修饰的jar包。并且可以以传递依赖的方式被其他项目直接引用。 - provided
provided修饰的jar包并不会直接打包到项目lib目录中,仅保证项目编译和测试的classpath中的文件在引用该jar包时不会报错。保证项目运行时正常。适用场景:承载项目的容器默认提供了该jar包,例如:java web项目需要使用相关servlet-api.jar,需要在pom中显式声明该jar,但是web容器例如:tomcat,提供该jar包支持。故无需在打包时将jar打包进来。另引用的父项目下有可能也声明了同类jar,在打包时设置<scope>provided</scope>
可以排除引用该jar包因为版本问题导致的冲突和错误,减少包的大小。
通过provided修饰的jar包,在ide中通过main方法执行时,引用相关方法,会报class not found的运行时异常。但是能正常打包,编译器编译检测也能通过,打出的包在容器中运行,如果容器提供相应包,程序将正常执行。项目启动时,使用java -Dloader.path=libs(文件夹) -jar指定依赖的引用路径。
- runtime
被修饰的jar包在编译时和打包时并不会被引用,打包的lib目录不会存在该jar包,只在运行时和测试时进行使用 - test
被修饰的jar只在测试编译和执行阶段使用,不会在项目正常运行时和编译的时候使用。 - system
与provided一样,被修饰的jar包并不会被打包到lib目录中,而是在运行时和编译时从特定的目录中去引用,而不是从maven的仓库中引用。需要同<systemPath>
一起使用,指定依赖jar包的目录。
注:<systemPath>
标签仅能与scope为system的属性一起使用,并且指定的路径为绝对路径。后续可能会被替代:
- import
仅可在<dependencyManagement>
标签中使用。等价于<parent>
。项目中往往会有自定义的<parent>
引用,对于框架的引用,例如spring-boot,可放在<dependencyManagement>
标签中使用。例如:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
等价于
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>