Maven依赖关系详解

Maven的依赖对小白来说是一个新的概念,只之前的说法都是导入某一个JAR包。但是到了maven中换个ming名次,但是作用还是一样、将第三方包添加到项目中。Maven的依赖是基于xml的配置,主要节点名称为 、读音的话只能附上音标了[dɪˈpendənsi]。今天主要整理这个节点的其中一个属性 scope。

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、排队依赖,当包通过传递,产生了冲突时可能通过排队依赖关系解决,如项目依赖dubbo、但项目本身又包含springframework ,则此时项目中的springframework会和dubbo中的springframework发生冲突。这时可以使用exclusions将dubbo中的springframework排除。
com.alibaba
dubbo
2.5.3


spring
org.springframework


如果想清除全部依赖也可以用如下写法:


com.alibaba
dubbo
2.5.3


*
*


4、依赖的冲突解决办法

当系统出现了NoSuchMethodError,LinkageError很有可能是你系统中出现了依赖冲突、具体可以按以下的步骤执行

1.在eclipse中查找冲突的类在哪些依赖包里面出现了,确定实际要使用的是那个包,冲突的包有哪些。

2.通过mvn dependency:tree  >  tree.txt 导出全部的依赖。

3.在导出的依赖文件中,查找问题相关的jar。确定这些jar是如何被依赖进来的,是直接依赖的还是通过传递依赖引入的。

4. 并分析冲突的原因,根据不同原因处理解决冲突:

  • 同一个jar包但groupId, artifactId不同,可通过上面提到的 来进行排除
  • 需要的版本jar包依赖路径较长,这种冲突可以把想要版本的依赖直接什么在依赖中,这样路径就最短了优先级最高。

5.最后可以通过打包mvn install 来确认打出来的war包中是否有被排除的依赖。

你可能感兴趣的:(eclipse插件,java,maven)