一.依赖范围
一个项目要想使用别的jar包提供的功能,需要通过依赖将jar包引入到项目的classpath路径中,maven中提供了编译、测试、运行三种classpath,因此所以scope的值就是控制与三种classpath的关系。目前可用5个值:
• compile,缺省值,适用于所有阶段。
• provided,类似compile,编译和测试时有效,最后是在运行的时候不会被加入。官方举了一个例子。比如在JavaEE web项目中我们需要使用servlet的API,但是呢Tomcat中已经提供这个jar,我们在编译和测试的时候需要使用这个api,但是部署到tomcat的时候,如果还加入servlet构建就会产生冲突,这个时候就可以使用provided。
• runtime,适用运行和测试阶段,如JDBC驱动。
• test,只在测试时使用,用于编译和运行测试代码,不会随项目发布。
• system,与本机系统相关联,可移植性差。编译和测试时有效。
• import,导入的范围,它只在使用dependencyManagement中,表示从其他pom中导入dependecy的配置。
例子:把A中的构建导入到B中。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>B</artifactId>
<packaging>pom</packaging>
<name>B</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>maven</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
二.依赖传递
在正常开发中,我们也会封装maven构建供小伙伴们使用,在我们使用自定义的构建中,那么我们自定义的构建中依赖的构建,也会依赖传递过来。
在maven的install命令小结中,已经在demo1项目中引入了demo的jar包,下面来演示一下依赖传递。
1.运行mvn install将demo1项目打包到本地仓库中
2.新建一个demo2项目,在项目中引入demo1的jar包
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.steven.maven</groupId><!--项目的包名-->
<artifactId>demo1</artifactId><!--项目的模块名(项目名)-->
<version>1.0-SNAPSHOT</version><!--快照版本-->
</dependency>
</dependencies>
3.编译demo2,可以看到demo和demo1的jar都被加载到项目中来了
三.依赖排除
上面演示了传递依赖,但是如果我们只需要依赖demo1 并不想依赖demo怎么办呢?这个时候就要是用exclusions 排除依赖列表。
在demo2中排除依赖demo的pom.xml配置
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.steven.maven</groupId><!--项目的包名-->
<artifactId>demo1</artifactId><!--项目的模块名(项目名)-->
<version>1.0-SNAPSHOT</version><!--快照版本-->
<!--排除依赖传递列表 -->
<exclusions>
<exclusion>
<groupId>com.steven.maven</groupId>
<artifactId>demo</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
四.依赖冲突(短路优先)
由于依赖的传递性,就会产生依赖冲突,maven采用最短路径和先声明先使用策略来解决。 比如,在demo中添加一个6.02版本的mysql依赖,在demo1中添加一个6.06版本的mysql依赖。
1. 在demo中添加一个6.02版本的mysql依赖,重新install
2. 在demo1中添加一个6.06版本的mysql依赖,重新install
3. demo2依赖demo1, demo1依赖demo,此时根据短路优先原则,demo2则会依赖6.06版本
五.依赖冲突(先声明先使用)
1.去除依赖
2.在demo2中依次引入demo和demo1依赖
demo依赖6.02版本,demo1依赖6.06版本,根据先声明先使用原则 demo2则应该依赖demo的6.02版本。