Maven依赖中scope的作用

Maven依赖中scope的作用

简介

scope是依赖的一个属性,主要用来限制依赖传递,并决定该依赖会不会包含到对应的类路径中

链接

maven官网

分类

  • 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

    1. pom.xml的依赖scope修改为test
    <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-classic</artifactId>
         <scope>test</scope>
         <version>1.3.0-alpha5</version>
    </dependency>
    
    1. 将上面的LogTest.java挪到test目录

    此时编译运行都没问题

    但是如果放在main目录下,则编译运行都报错

上一篇:使用美丽的汤从非类节中获取数据


下一篇:是否可以使用Python / BeautifulSoup从HTML EXCEPT锚点/链接中剥离所有标签?