maven在编译、测试和运行的时候使用的是三套不一样的classpath,pom中的依赖配置项的scope属性就是用来配置该依赖项在哪一个范围内生效。Maven有下边几种依赖范围:java
compile:编译依赖范围。若是没有依赖包没有指定scope属性,那么默认状况下就是此依赖范围。这个依赖范围对于编译、测试和运行三种classpath都有效。好比说spring-beans这个依赖包。spring
test:测试依赖范围。只对测试classpath有效。在编译主代码或者运行项目的时候是没法使用此包的。好比说junit。sql
provided:已提供依赖范围。对于编译和测试的classpath有效,在运行无效。好比说servlet-api,在编译和测试的时候须要这个依赖包,但在项目运行的时候不须要。由于tomcat已经提供了这个包。api
runtime:运行时依赖范围。对于测试和运行的classpath有效,对于编译无效。好比jdbc驱动包。由于代码都是针对jdbc接口去写的,没有针对实现。因此在编译时即便没有驱动的实现包也是能够编译经过的。但若是要测试或者运行的时候,就要加载实现包了。tomcat
system:系统依赖范围。该依赖与三种classpath的关系相似于provided。但必须与systemPath元素配合使用才能够,但这种状况虽然能够指定系统的jar包路径,但形成了与本机绑定的状况,没法移植maven
<dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-my</artifactId> <version>1</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency>
依赖范围 | 编译classpath有效 | 测试classpath有效 | 运行classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-beans |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驱动实现 |
system | Y | Y | - | 本地的,maven仓库以外的类库文件 |
假如项目A的依赖关系是A->B-C-X(1.0),A->D-X(2.0)。这个时候有两个版本的X,那么选哪个呢。maven依赖调解的第一个原则是路径短者优先
。因此会引入X的2.0版本。ide
若是依赖路径的长度相同的话,该怎么处理呢?好比说A-B-Y(1.0),A-C-Y(2.0)。这个时候会应用第二个原则最早声明者优先
。若是B的依赖声明在C以前,那么引入的Y的版本就是1.0.测试
好比说这样的依赖关系A->B,B->X(可选),B->Y(可选)。假如A对B的依赖范围是compile,B对X和Y的依赖范围也是compile,那么根据依赖的传递性,A也会引入X和Y。可是这里X和Y对B来讲是可选依赖,A就不会引入X和Y。A若是要使用X和Y须要单独引入!spa
<optional>true</optional>
依赖的传递性能够很方便的引入项目须要的依赖,但也存在一些问题。假如A->B,B->C。可是这里的C是SNAPSHOT版本的,会影响项目的稳定性。因此在构建A项目的时候须要把这个快照版本排除掉,单独的在A的pom文件中申明对C的可靠版本的依赖。code
<project> <groupId>com.clgate.cn</groupId> <artifactId>A</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>com.clgate.cn</groupId> <artifactId>B</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>com.clgate.cn</groupId> <artifactId>C</artifactId> </exclusions> </exclusions> </dependency> <dependency> <groupId>com.clgate.cn</groupId> <artifactId>C</artifactId> <version>1.1.1</version> </dependency> </dependencies> </project>
主要的目的就是统一相同groupId,不一样artifactId的版本
<project> xxxxx xxxxx xxxxx <properties> <spring.version></spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </project>