Maven依赖范围的分类
maven项目中有3套classpath:编译classpath、测试classpath、运行classpath。
1.compile
默认范围,当我们引入依赖时,如果<scope>标签没有指定,那么默认就是complie。比如spring:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
意义:3个classpath环境中都能使用,并且项目打包时,也会将这些依赖打包进去。
2. test
测试范围有效,比如Junit相关的测试包:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
意义:只在测试的classpath中才能够使用。在src/main/java里面的代码是无法使用这些api的,并且项目打包时,也不会将"test"标记的<scope>打入"jar"包或者"war"包
3. provide
编译范围和测试范围有效,比如servlet相关的jar包。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provide</scope>
</dependency>
意义:只有在编译的classpath和测试的classpath有效。当项目运行时,是不会使用<scope>provide</scope>标记的依赖,项目打包时也不会打入。
因为servlet容器(如Tomcat)已经提供了servlet的jar,如果我们还将servlet打入jar或者war包中,那么在容器中运行时反而会出现异常。
4. runtime
运行时范围有效。比如mysql驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
<scope>runtime</scope>
</dependency>
意义:项目在测试classpath和运行classpath中有效。因为在编码时只会使用JDK提供的jdbc接口,而具体的实现是有对应的厂商提供的驱动(如mysql驱动),实在运行时生效的。
5. system
系统范围依赖,作用范围与"provide"一致。需要配合<systemPath></systemPath>标签使用指定依赖文件的路径。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.10.release</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
由于此类依赖不是由maven仓库解析的,是在代码里面写死的,当你同事的路径与你的路径不一致时,就需要修改路径,所以移植不方便,很少使用。