Maven在编译,测试和运行时使用的是不同的ClassPath, 所以Maven通过dependency的scope来定义不同的classpath应该包含哪些依赖。
定义依赖
- compile: 编译依赖范围。如果没有指定,聚会默认使用该依赖范围,使用此依赖范围的Maven依赖,对于编译、测试和运行三种classpath都有效。在编译、测试和运行的时候都要使用该依赖
- test:测试依赖范围。 是用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目时将无法使用此依赖。
- provided: 已提供依赖范围,对于编译和测试classpath有效,但是在运行时无效。编译和测试项目的时候需要该依赖,但是在运行该项目的时候,由系统提供,所以不需要maven重复引入。
- runtime: 运行时依赖范围,对于runtime和测试classpath有效,但是在编译代码时无效,典型的就是JDBC的驱动实现,项目在编译时候只需要使用JDK提供的JDBC接口,只有在执行测试或者运行的时候才需要JDBC具体的驱动实现。
5: system: 系统依赖范围,该依赖与provided的依赖范围是一只的,但是,使用system依赖范围必须通过systemPath元素显式的指定依赖文件的路径。此依赖不是通过maven仓库解析,而是与本机绑定的,可能会造成不可移植的问题。
6: import: 导入依赖范围,该依赖不会对三种classpath有任何实际的影响。 一般用在dependency management中,设定依赖的默认版本。
依赖传递
在maven中,依赖是具有传递性的,例如项目依赖Spring-core, spring-core又依赖common-log,name项目就依赖common-log。这些间接依赖的范围又是如何定义呢?
这个我们需要分组进行分析。
- 间接依赖为compile时,则依赖关系与直接依赖相同
- 间接依赖为test时,则无论直接依赖是什么都没有依赖关系
- 间接依赖为provided时, 直接依赖为provided时,依赖关系为provided; 直接依赖为其他时,则没有依赖依赖
- 间接依赖为runtime时, 直接依赖为compile时,依赖关系为runtime
直接依赖关系为test时, 依赖关系为test
直接依赖关系为provided时, 依赖关系为provided
直接依赖关系为runtime时,依赖关系为runtime
依赖调解
在大多数情况下我们只需要关心项目的第一级依赖,可是有时候间接依赖可能会导致意想不到的冲突,这时候我们就需要对maven的选取机制有一定的了解。maven选取机制有两大原则。
- 路径最短原则: 传递依赖的层级越少,则优先选用。
项目A ->D->E->C(2.0)
项目A -> B ->C(1.0)
则项目A依赖C(1.0),因为C(1.0)的路径为2。 - 第一声明者优先原则: 当依赖层级相同时,则查看依赖的顺序,顺序优先者优先选用。
项目A ->D->C(2.0)
项目A -> B ->C(1.0)
则项目A依赖C(2.0),因为C(2.0)与C(1.0)的路径都为2,可是C(2.0)在C(1.0)之前被依赖。
可选依赖
当依赖属性optional为true则为可选依赖,当依赖为可选依赖时,依赖不具有传递性。
网友评论