1、依赖范围
依赖范围由<dependency></dependency>
标签中<scope></scope>
标签来定义。
项目如果要使用某个框架或依赖,需要把相关jar包引用到classpath中,maven项目提供了三个classpath:编译、测试、运行。
依赖的范围用于控制依赖于三种classpath关系的,包括:compile、provided、runtime、test、system、import
compile:默认范围,编译、测试、运行都有效
provided:编译和测试有效,最后运行不会被加入,如tomcat依赖
runtime:在测试和运行的时候有效,编译不会被加入,比如jdbc驱动jar
test:测试阶段有效,比如junit
system:与provided一致,编译和测试阶段有效,但与系统关联,可移植性差
import:导入的范围,它只是用在dependencyManagement中,表示从其它的pom中导入dependency的配置
- 1
- 2
- 3
- 4
- 5
- 6
- 7
例如:
<dependency>
<groupIdjunit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<!-- 只在测试阶段使用该依赖 -->
<scope>test</scope>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
<!-- 只在编译、测试期有效,在运行期无效,运行期使用tomcat容器自己的jar包 -->
<!-- servlet support -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- jsp support -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
2、依赖传递
比如:A项目依赖B,B项目依赖C,此时C项目就会传递到A项目中。
C项目:
<groupId>com.jsun.test</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
- 1
- 2
- 3
B项目:
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
A项目:
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
查看项目maven依赖列表,如图:
C项目自动被引入到A项目中,这就是依赖传递的结果。
3、依赖排除
如果此时,A项目依赖B项目,无需依赖C项目,那么需要把自动传递的依赖排除掉,通过<exclusions>
标签实现。
A项目引用B项目依赖时,主动排除传递的C项目依赖,修改A项目pom.xml
代码:
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.jsun.test</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
还可以通过,C项目被B项目引用时,主动禁止自己被传递,只在B项目中使用,通过<optional>true</optional>
实现,修改B项目的pom.xml:
<dependency>
<groupId>com.mavan.demo</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
<optional>true</optional>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
效果如图:
A项目的maven依赖列表中只有B项目,而C项目自动被排除了。
补充:如果想把当前依赖的所有传递依赖排除掉,可以使用通配符*
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
4、依赖冲突
依赖引用有两个原则:
1)、短路优先原则:优先引用路径短的依赖
比如现在有两个依赖路径:(1)A–>B–>C–>X.1,(2)A–>B–>X.2,则(2)路径被优先解析,A项目使用X的版本为X.2版本。
比如A项目依赖B项目,B项目依赖C项目,B项目依赖commons-io的2.4版本,C项目依赖commons-io的2.0版本,则A项目的maven依赖列表中出现的是commons-io的2.4版本:
B项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
C项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
maven依赖列表如图:
2)、路径相同,先声明优先原则
比如,A项目依赖B项目,A项目依赖C项目,B、C项目分别依赖commons-io的2.4和2.0版本,A项目引用B、C依赖时,C引用放在B前面,则A使用的是commons-io的2.0版本。
B项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
C项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
A项目:
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
查看A项目maven依赖列表,如图: