逐步学习maven——maven依赖(范围 传递 排除 冲突)
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的配置
例如:
<dependency>
<groupIdjunit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<!-- 只在测试阶段使用该依赖 -->
<scope>test</scope>
</dependency>
<!-- 只在编译、测试期有效,在运行期无效,运行期使用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>
2、依赖传递
比如:A项目依赖B,B项目依赖C,此时C项目就会传递到A项目中。
C项目:
<groupId>com.jsun.test</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
B项目:
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
A项目:
<dependency>
<groupId>com.jsun.test</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
查看项目maven依赖列表,如图:

C项目自动被引入到A项目中,这就是依赖传递的结果。
3、依赖排除
当A项目依赖B而无需C时,则应通过<exclusions>标签来实现对自动传递依赖性的排除。
当A引用B而不需C时主动地将C项目的传递性移除,并相应地修改其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>
此外,在C项目被B项目引用的情况下,可以通过<optional>true</optional>来实现对自身传递的主动禁止,并仅在B项目中进行配置。
<dependency>
<groupId>com.mavan.demo</groupId>
<artifactId>C</artifactId>
<version>0.0.1-SNAPSHOT</version>
<optional>true</optional>
</dependency>
效果如图:

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>
4、依赖冲突
依赖引用有两个原则:
1)、短路优先原则:优先引用路径短的依赖
比如现在有两个依赖路径:(1)A–>B–>C–>X.1,(2)A–>B–>X.2,则(2)路径被优先解析,A项目使用X的版本为X.2版本。
例如,在Maven构建工具中
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
C项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
maven依赖列表如图:

2)、路径相同,先声明优先原则
例如,在构建过程中,请注意以下几点:首先,在构建过程中,请确保所有必要的组件都已正确配置;其次,在配置Maven插件时,请优先设置JDK环境变量;最后,在配置完成后,请确保所有JDK实例都已成功启动。
B项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
C项目:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
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>
查看A项目maven依赖列表,如图:

