简介
本文介绍maven的依赖的范围、传递、排除的用法。
依赖范围
概述
范围(scope)定义了类包在项目的使用阶段。项目阶段包括: 编译,运行,测试和发布(打包)。
项 | 说明 | 依赖是否传递 |
compile | 默认值。表示当前依赖参与项目的所有阶段(编译,运行,测试和发布),属于强依赖。 | 是 |
provided | 参与编译,运行,测试,不参与发布。 类似compile,区别在于不参与发布(打包阶段进行了exclude操作)。 此依赖的发布由运行的环境来提供,比如tomcat或者基础类库等等。 | 否 |
system | 使用上与provided相同。 不同之处:该依赖从本地文件系统中提取(需要显式提供包含依赖的jar),而不是从maven仓库中提取,其会参照systemPath的属性进行提取依赖。 | 否 |
test | 只在测试时使用,参与编译、运行、测试。不会随项目发布。 | 否 |
runtime | 只在运行时使用。参与运行和测试阶段。 一般这种类库都是接口与实现相分离的类库,比如JDBC类库,在编译之时仅依赖相关的接口,在具体的运行之时,才需要具体的mysql、oracle等等数据的驱动程序。 | 否 |
import | 用来导入dependencyManagement中的dependencies中的dependency import只能在dependencyManagement的中使用。 能解决maven单继承问题 import的依赖关系没有传递性。(相当于:将依赖管理复制粘贴过来) | 否 |
问题解决示例
SpringBoot代码上加了测试
HelloApplicationTests.java(所在路径:src/main/java/com.example.rabbitmqhello)
package com.example.rabbitmqhello;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = HelloApplication.class)
public class HelloApplicationTests{
@Autowired
private Sender sender;
@Test
public void hello() throws Exception {
sender.send();
}
}
发现@RunWith(SpringJUnit4ClassRunner.class)被标红,鼠标放上去提示:Cannot resolve symbol "SpringJUnit4ClassRunner"
原因
测试类一般是放在src/test/java,而不是放在src/main/java下。maven在编译的时候,src/main/java下是不引用<scope>test</scope>的jar,而编译src/test/java下的测试这会引用<scope>test</scope>的jar。
本处在src/main/java中使用测试注解,但不会引用到相关类,就会找不到SpringJUnitClassRunner.class。
解决方法
法一:将测试包的<scope>test</scope>改为<scope>compile</scope>
法1:直接修改pom.xml
法2:File=> Project Structure=> Project Settings=> Modules=> 选中相应模块=> Dependencies=> 修改相应包为compile
法二:将代码所在文件夹属性设为test
法1:将代码放到src/test/java下
法2:将所在文件夹标记为Test:右键此文件夹=> Mark Directories As=> Test Sources Root
依赖的传递
描述
假设:A依赖了B,B依赖了C,那么A是否将C依赖引入进来呢?这就是依赖传递问题。
详述
- 默认情况(compile)A是会将C引入进来的。
- B引入C时,scope为compile,写法如下:
<dependency>
<groupId>xxx</groupId>
<artifactId>C</artifactId>
<version>xxx</version>
</dependency>
- 如果B通过provided的形式引入C,则A不会引入C
- 写法如下:
<dependency>
<groupId>xxx</groupId>
<artifactId>C</artifactId>
<version>xxx</version>
<scope>provided</scope>
</dependency>
依赖传递示例
依赖传递示例
- mybatis-plus会引入mybatis
- knife4j会引入swagger
依赖不传递示例
- openfeign不引入okhttp
依赖的排除
依赖的排除:如果我们不想通过 A-> B-> C->D1 引入 D1 的话,那么我们在声明引入 A 的时候将 D1 排除掉。
排除的原因一般有:1.依赖不够/不够稳定 2.与其他的包冲突(名包相同)
示例:将 redis 的 lettuce依赖排除
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!--不依赖Redis的异步客户端lettuce -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
排除所有依赖
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>