一、Maven简介
Maven是一个跨平台的项目管理工具。作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理。
二、Maven的依赖管理
1、依赖配置
基本配置:
...
...
...
...
...
...
...
...
...
...
...
...
大部分依赖声明只包含基本坐标
2、依赖范围
Maven在编译主代码的时候需要使用一套classpath,在编译和执行测试的时候会使用另一套classpath,实际运行项目的时候,又会使用一套classpath。
3、传递性依赖
传递性依赖是在maven2中添加的新特征,这个特征的作用就是你不需要考虑你依赖的库文件所需要依赖的库文件,能够将依赖模块的依赖自动的引入。例如我们依赖于spring的库文件,但是spring本身也有依赖,如果没有传递性依赖那就需要我们了解spring项目依赖,自己添加到我们的项目中。有了传递性依赖机制,在使用Spring Framework的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖。Maven会解析各个直接依赖的POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。
例如:项目中用到spring-core,而它又依赖commons-logging,从其构件POM http://repo1.maven.org/maven2/org/springframework/spring-core/4.3.2.RELEASE/spring-core-4.3.2.RELEASE.pom中可以看出
-
4.0.0
org.springframework
spring-core
4.3.2.RELEASE
Spring Core
Spring Core
https://github.com/spring-projects/spring-framework
-
Spring IO
http://projects.spring.io/spring-framework
-
-
The Apache Software License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
repo
-
-
jhoeller
Juergen Hoeller
[email protected]
-
scm:git:git://github.com/spring-projects/spring-framework
scm:git:git://github.com/spring-projects/spring-framework
https://github.com/spring-projects/spring-framework
-
Jira
https://jira.springsource.org/browse/SPR
-
-
commons-codec
commons-codec
1.10
compile
true
-
commons-logging
commons-logging
1.2
compile
-
log4j
log4j
1.2.17
compile
true
-
net.sf.jopt-simple
jopt-simple
5.0.2
compile
true
-
org.aspectj
aspectjweaver
1.8.9
compile
true
可以看出还依赖了其他构建。Maven就是根据次POM文件获得它的依赖的,从而实现传递性依赖。
假设A依赖于B,B依赖于C,我们说A对于B是第一直接依赖,B对C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。
|
compile | test | provided | runtime |
compile | compile | --- | --- | runtime |
test | test | --- | --- | test |
provided | provided | --- | provided | provided |
runtime | runtime | --- | --- | runtime |
|
4、maven对传递性依赖的处理
有些依赖,maven会对其按照下述原理自动处理
1).短路优先:谁离得最近就使用谁的依赖jar包
C到达A为C->B->A
C到达B为C->B
例如:
A中的 commons-io的版本为2.4
B中的commons-io的版本为2.0
C中依赖于B,B依赖于A
则C的junit的包为2.0版本
因为依赖的短路优先
2).如果两条路都是一样长的时候呢?
C到达A为C->A
C到达B为C->B
则看pom文件中依赖的两个工程谁在前面就是用哪个版本
例如:
这里使用的common-io为2.4版本
org.lonecloud.A
A
0.0.1-SNAPSHOT
org.lonecloud.B
B
0.0.1-SNAPSHOT
C文件中添加了A和B的依赖项的时候谁最先加载则使用谁的jar包
下面使用的是2.0的版本,也就是B中的jar包
org.lonecloud.B
B
0.0.1-SNAPSHOT
org.lonecloud.A
A
0.0.1-SNAPSHOT
三、Maven依赖jar包冲突解决
1、判断jar是否正确的被引用
1)、在项目启动时加上VM参数:-verbose:class
项目启动的时候会把所有加载的jar都打印出来 类似如下的信息:
classpath加载的jar
具体load的类
我们可以通过上面的信息查找对应的jar是否正确的被依赖,具体类加载情况,同时可以看到版本号,确定是否由于依赖冲突造成的jar引用不正确;
2)、 通过maven自带的工具:mvn dependency:tree
具体后面可以加 -Dverbose 参数 ,详细参数可以去自己搜,这里不详细介绍。
比如分析如下POM
运行: mvn dependency:tree -Dverbose
输出结果:
通过里面的信息可以看到 两个jar都commons-logging存在依赖,但是版本不同。里面的详细信息显示引用了 commons-logging:commons-logging:jar:1.1 去掉了commons-logging:commons-logging:jar:1.0.3 (omitted for duplicate)。
3)、在Myeclipse或者idea或者eclipse中用pom编辑器打开一个pom文件,在Dependency Hierarchy的Tab页中,就可以查看当前pom文件中显示声明的jar包,及这些显示声明的jar中隐式引入的依赖jar包。
通过以上方法我们可以看到项目中引用jar版本号;接下来就是如何排除掉我们不想要版本的jar;
2、冲突的解决
1)在pom.xml中引用的包中加入exclusion,排除依赖
com.alibaba
dubbo
2.5.3
spring
org.springframework
去除全部依赖
com.alibaba
dubbo
2.5.3
*
*
2)在ide中右击进行处理,处理完后在pom.xml中也会添加exclusion元素