Maven的依赖对小白来说是一个新的概念,只之前的说法都是导入某一个JAR包。但是到了maven中换个ming名次,但是作用还是一样、将第三方包添加到项目中。Maven的依赖是基于xml的配置,主要节点名称为
scope它主要管理依赖的部署,主要有如下5个范围可用:
compile
compile是默认值,适用于所有阶段,如编译、打包、测试。会随着项目一起打包、发布。
test
test只在测试时使用,用于编译和运行测试代码。不会随项目发布、如junit。
runntime
runntime只在运行时使用,无需参与项目的编译。如oracle jdbc驱动架包,一般scope为runntime、你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
provided
provided意味着打包的时候可以不用包进去,例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。不会被打包。
system
system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素
scope的依赖传递
1、当scope为test时不会传递到引用这个项目的其它项目,但如果不是test会传递依赖到其它项目。
如:项目A中有一个依赖包junit4.10,它的作用域是test
现在有一个项目B,引用项目A,如果项目B要使用junit4.10就必须自己重新定义依赖关系。【因为不会传递依赖,所以不会从项目A中得到】
但:如果作用域是其它的,不是test
那么项目B可以直接使用不用自己再定义一个依赖关系。【因为会从项目A中自动传递依赖,而得到】
2、同级别依赖
-->(依赖)
项目A-->P包1.0
项目B-->P包2.0
项目C-->项目A,项目B
项目C得到的P包,应该是哪个呢?
应该是项目A的P包1.0,因为在项目C中,项目A依赖关系定义在前,项目B的依赖配置定义在后。
3、不同级别依赖,层级少的优先依赖
如:
A-->P1.0
B-->A
C-->B
D-->P2.0
E-->C,D 那么,E通过传递依赖得到的将会是:P2.0 (就算E中的C依赖定义在前面)
3、排队依赖,当包通过传递,产生了冲突时可能通过排队依赖关系解决
如果想清除全部依赖也可以用如下写法:
4、依赖的冲突解决办法
当系统出现了NoSuchMethodError,LinkageError
很有可能是你系统中出现了依赖冲突、具体可以按以下的步骤执行
1.在eclipse中查找冲突的类在哪些依赖包里面出现了,确定实际要使用的是那个包,冲突的包有哪些。
2.通过mvn dependency:tree > tree.txt 导出全部的依赖。
3.在导出的依赖文件中,查找问题相关的jar。确定这些jar是如何被依赖进来的,是直接依赖的还是通过传递依赖引入的。
4. 并分析冲突的原因,根据不同原因处理解决冲突:
5.最后可以通过打包mvn install 来确认打出来的war包中是否有被排除的依赖。