想必大家在maven的pom.xml文件中 定义依赖 除了 groupId ,artifactId,version三个必要的标签外,还见过 另外一个标签scope(如下)。没错这个标签就是我下面要说的依赖范围。
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency></dependencies>其实maven中的依赖范围有很多种,但是我们常用的只有以下三种,我们掌握这三种就够用了。他们分别是 compile (编译)范围依赖,test(测试)依赖,provided依赖。那问题来了我们在定义依赖的时候 这个scope 该怎么填呢?我们先讲一下判定规则:
是否对main主程序有效
是否对test测试程序有效
是否参与打包
是否参与部署
其实可以把这三个依赖分为两种情况
针对程序结构(分主程序和测试程序)的依赖
我们在前面就讲过 maven project 遵循着一定目录结构
complie 编译范围的依赖 (典型例子 spring-core 对main和test都有效,参与打包参与部署)
test 测试范围的依赖 (典型例子junit 只对test有效,不参与打包参与部署)
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency> 针对开发过程的依赖provided 范围的依赖(典型例子servlet-api 在开发过程中必须提供(添加tomcat运行时环境/添加maven依赖),打包过程中忽略,运行时有servlet容器提供) <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>servlet-api</artifactId> <version>6.0.32</version></dependency> 2.依赖传递
为了证明依赖会传递我分别建了一个A模块 依赖junit 和spring-core;B模块依赖junit和A模块如下:
我们用idea的依赖树来看下 A模块,B模块这两个模块的依赖关系树:
先是A模块的 dependency tree
再是B模块的关系树 dependcy tree
从B的pom.xml 代码中,我们可以看出 B模块在pom.xml文件中并没有直接的配置Spring-core的依赖,但是从B的依赖关系树种我们可以看出B也依赖了spring-core,只是这个依赖关系是因为 A依赖了spring-core ,而B又依赖了A所以 B也间接的依赖了spring-core因此可以得出一个结论:
依赖可以相互之间传递
在某些情况下我们可能需要依赖某个a.jar,但又不想间接依赖这个a.jar所依赖的jar包,这时我们可以采用exclusion 来排除某个依赖。 如下:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.6.RELEASE</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions></dependency> 4.依赖原则我们在工作中的项目都是分模块的,而且模块之间又互相依赖,这个时候我们可能会引入相同的依赖 ,这时maven取那个依赖呢?这就是maven依赖的原则:
路径不同间接依赖中maven采用的是路径最短者优先路径相同间接依赖中maven 采用的是依赖定义顺序从上到下我们可以通过以下来验证这两个依赖原则的正确性,定义一个A模块分别依赖junit 与spring-core-4.2.7; 定义一个B模块 依赖与junit与A模块 与spring-core-4.3.7;定义一个C模块分别依赖junit与B;定义一个D模块 分别依赖A模块与C模块。然后根据
C模块与D模块最后依赖的spring-core的版本来验证上述两个依赖原则。
A模块
B模块
C模块
根据C模块的依赖关系树 如下
D模块则分两种情况:
1.B模块先定义与
A依赖定义优先B依赖