Maven依赖中scope的作用
简介
scope是依赖的一个属性,主要用来限制依赖传递,并决定该依赖会不会包含到对应的类路径中
链接
分类
-
compile
【系统默认】该scope表示这个依赖会贯穿整个应用的生命周期,比如编译-运行-测试
-
provided
该scope表示这个依赖只在编译和测试时会被加载,在运行时不会加载;
比如tomcat等容器类相关依赖,因为web应用都是部署在tomcat等容器中,所以程序在部署时不需要这个依赖
-
runtime
该scope表示这个依赖只在运行和测试时会加载,编译不会加载
-
test
该scope表示这个依赖只在测试时才会加载
比如JUnit等测试依赖
-
system
【已废弃】
-
import
该scope用在
<dependencyManagement>
标签中,搭配<type>pom</type>
属性一起用,表明这个依赖会被对应的pom文件中的所有依赖替代因为pom文件只能有一个parent(即只能继承一个pom),但是通过import,可以导入多个pom依赖
例子
下面用示例来说明各个scope的区别
LogTest.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest {
static Logger log = LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
log.info("b");
}
}
pom.xml
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.0-alpha5</version>
</dependency>
</dependencies>
如上所示,有一个测试类LogTest.java
和一个pom.xml
,其中pom中的依赖scope没有显示指定,则默认为compile
-
compile
此时编译、运行项目都没问题
-
provided
将
pom.xml
的依赖scope修改为provided
<dependencies> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <scope>provided</scope> <version>1.3.0-alpha5</version> </dependency> </dependencies>
此时编译没问题,但是运行时报错如下,因为运行时不会去项目中加载这个依赖,而是去本地的类路径查找(但是本地只是Java环境,并没有logback依赖)
PS:可以通过查看控制台的java运行命令,查看具体查找了哪些路径
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory at LogTest.<clinit>(LogTest.java:5) Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 1 more Exception in thread "main"
-
runtime
将
pom.xml
的依赖scope修改为runtime
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <scope>runtime</scope> <version>1.3.0-alpha5</version> </dependency>
此时编译时报错如下,因为runtime指定的范围就是运行以及测试才会加载,编译不加载
Error:(1, 17) java: 程序包org.slf4j不存在 Error:(2, 17) java: 程序包org.slf4j不存在
runtime
的作用主要是让我们在代码中直接依赖接口或抽象(比如 JDK的JDBC接口),然后在运行时再去依赖真正的实现(比如 mysql-connector-jar)比如MySQL驱动依赖
mysql-connector-jar
,就可以设置为runtime
,然后通过JDBC抽象层来间接的使用 -
test
- 将
pom.xml
的依赖scope修改为test
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <scope>test</scope> <version>1.3.0-alpha5</version> </dependency>
- 将上面的LogTest.java挪到test目录
此时编译和运行都没问题
但是如果放在main目录下,则编译和运行都报错
- 将