maven有以下几种依赖范围:

  • compile编译依赖范围这个是默认的依赖范围,使用这个依赖范围的依赖,对于编译、测试、运行三种classpath都有效。

  • test测试依赖范围。这个只对测试classpath有效,在编译和项目运行的时候是无法使用此类依赖的,例如JUnit依赖。

    1
    2
    3
    4
    5
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
    
  • provided已经提供的依赖。这种依赖只对编译和测试的时候有效,运行的时候不会使用这类依赖,例如servlet-api,在编译和测试项目的时候,都需要使用到这个依赖,在项目运行的时候,容器会提供这个依赖。

    1
    2
    3
    4
    5
    6
    
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    
  • runtime运行时依赖。使用此依赖范围的maven依赖,对于测试和运行的时候有效,但是在编译的时候无效。例如JDBC驱动依赖,项目编译的时候只需要依赖jdk提供的接口就可以了,只有在运行的时候才需要具体的实现。

    1
    2
    3
    4
    5
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • system系统依赖,这个生效的范围和provided一样的,都是编译和测试的时候生效,这种依赖必须通过systemPath元素显式地指定依赖文件的路径。这种依赖往往和本机的系统绑定,可能会造成构建的不可移植性。

    1
    2
    3
    4
    5
    6
    7
    
    <dependency>
        <groupId>jdk.tools</groupId>
        <artifactId>jdk.tools</artifactId>
        <version>1.7</version>
        <scope>system</scope>
        <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
    </dependency>
    

依赖范围生效的关系表如下所示:

依赖范围(Scope) 编译时有效 测试时有效 运行时有效 例子
compile Y Y Y 例如Spring的依赖
test N Y N JUnit
provided Y Y N servlet-api
runtime N Y Y JDBC驱动
system Y Y N 本地的jar包,例如rt.jar