之前我们做了3个模块,user-core、user-log和user-service,之间展现出了相互依赖的特性。
接下来我们要说依赖中几个比较重要的概念。
有没有发现我们的pom文件的<dependency></dependency>标签对可以设置一个<scope></scope>标签对,然后其中的值有compile、import、provided、runtime、system、test。
system和import我们先不说。说一下compile、provided、runtime和test。
compile:
我们的依赖范围是基于compile的依赖范围,也是我们的默认依赖范围。当<scope></scope>标签对中是compile时,它会在编译或打包的时候把依赖加进去,这就是compile的范围。
provided:
当我们编译、测试的时候会把依赖加进去,但是当我们打包的时候就不会把依赖加进去。(例如我们做Web需要Servlet-api.jar,但是我们的tomcat的lib中是有这个包的,我们最后给项目打包的时候如果把Servlet-api.jar依赖也加进去的话,就会发生冲突。)
runtime:
在运行的时候依赖,在编译的时候不依赖。
test:
在测试范围内依赖有效,在编译和打包的时候不会使用这个依赖。(例如我们使用的测试jar包junit,在项目正式启动后这个包就不需要了,所以我们仅在测试中使用这个依赖,编译和打包的时候就不需要了,即节省了编译压力提高了效率)
注意,如果我们将junit的scope设置成test,我们编译的时候只为test源文件夹下的类提供junit依赖,src下其它文件夹下的类不提供依赖,所以我们要注意,scope为test的依赖只能提供给test文件夹下的类,编写的时候注意使用范围。
我们注意到,我们的user-service模块集成了user-core和user-log两个模块,而且引用了后两者的依赖包,我们要注意,这里集成的依赖包是后两者编译compile范围内的依赖包,而不是所有的依赖包(scope不是默认的或不是compile)。
接来下我们来谈一下依赖里让人比较头疼的一些事。
假设我们有一个A项目,依赖了一个L-1.0.jar,然后我们有一个B项目,依赖了一个L-2.0.jar,然后我们又有一个C项目,及依赖于A,又依赖于B:
A--L1.0
B--L2.0
C--A,B
那么C项目是引用的L-1.0.jar呢,还是引用L-2.0.jar呢?我们来试验一下:
我们的user-core依赖的log4j版本是1.2.17:
我们的user-log依赖的log4j版本是1.2.9:
那集成这两个项目的user-service,使用的log4j是什么版本的?
我们看一下:
为什么?我们看一下user-service的pom文件:
发现我们是先引入的user-log,后引入的user-core:
所以先引入了log4j-1.2.9,然后引入user-core的时候发现已经存在log4j的jar,所以就没有重复引入。
所以ABC之间,A、B和L的依赖是直接依赖,C和L的依赖是间接依赖。当我们有了间接依赖之后,先声明了哪个使用该依赖的模块,就间接使用哪个依赖。
接下来看下一点:
如果级别相同,哪一个先写依赖哪一个,那么我们看一下这个情况:
我们现在将user-log和user-core的依赖先后调换一下:
首先看我们的log4j,使用的就是1.2.17了:
这一点是没有问题的,但是看我们的common-logging版本:
是1.1.1对吧?回来看一下我们user-core和user-log的common-logging版本:
我们打开user-core的pom的依赖级层图:
发现user-core的common-logging是间接依赖,也就是说是dbunit使用的common-logging。
而我们看一下user-log的common-logging的依赖关系:
发现是直接依赖关系。
所以,当依赖级别相同的时候,相同的jar,我们是哪个先被依赖就依赖那个模块的jar,前提是,此jar我们只依赖它“依赖层数”最短的jar。
这就是为什么会使用common-logging的1.1.1版本。
能不能限制某些依赖的使用呢?假设我们就想用common-logging的1.0.4版本,我们可在user-service的pom文件中这样修改:
这样就排除使用user-log的commons-logging包了,我们再看user-service的依赖,发现已经变成1.0.4版本:
接下来我们要说依赖中几个比较重要的概念。
有没有发现我们的pom文件的<dependency></dependency>标签对可以设置一个<scope></scope>标签对,然后其中的值有compile、import、provided、runtime、system、test。
system和import我们先不说。说一下compile、provided、runtime和test。
compile:
我们的依赖范围是基于compile的依赖范围,也是我们的默认依赖范围。当<scope></scope>标签对中是compile时,它会在编译或打包的时候把依赖加进去,这就是compile的范围。
provided:
当我们编译、测试的时候会把依赖加进去,但是当我们打包的时候就不会把依赖加进去。(例如我们做Web需要Servlet-api.jar,但是我们的tomcat的lib中是有这个包的,我们最后给项目打包的时候如果把Servlet-api.jar依赖也加进去的话,就会发生冲突。)
runtime:
在运行的时候依赖,在编译的时候不依赖。
test:
在测试范围内依赖有效,在编译和打包的时候不会使用这个依赖。(例如我们使用的测试jar包junit,在项目正式启动后这个包就不需要了,所以我们仅在测试中使用这个依赖,编译和打包的时候就不需要了,即节省了编译压力提高了效率)
注意,如果我们将junit的scope设置成test,我们编译的时候只为test源文件夹下的类提供junit依赖,src下其它文件夹下的类不提供依赖,所以我们要注意,scope为test的依赖只能提供给test文件夹下的类,编写的时候注意使用范围。
我们注意到,我们的user-service模块集成了user-core和user-log两个模块,而且引用了后两者的依赖包,我们要注意,这里集成的依赖包是后两者编译compile范围内的依赖包,而不是所有的依赖包(scope不是默认的或不是compile)。
接来下我们来谈一下依赖里让人比较头疼的一些事。
假设我们有一个A项目,依赖了一个L-1.0.jar,然后我们有一个B项目,依赖了一个L-2.0.jar,然后我们又有一个C项目,及依赖于A,又依赖于B:
A--L1.0
B--L2.0
C--A,B
那么C项目是引用的L-1.0.jar呢,还是引用L-2.0.jar呢?我们来试验一下:
我们的user-core依赖的log4j版本是1.2.17:
我们的user-log依赖的log4j版本是1.2.9:
那集成这两个项目的user-service,使用的log4j是什么版本的?
我们看一下:
为什么?我们看一下user-service的pom文件:
发现我们是先引入的user-log,后引入的user-core:
所以先引入了log4j-1.2.9,然后引入user-core的时候发现已经存在log4j的jar,所以就没有重复引入。
所以ABC之间,A、B和L的依赖是直接依赖,C和L的依赖是间接依赖。当我们有了间接依赖之后,先声明了哪个使用该依赖的模块,就间接使用哪个依赖。
接下来看下一点:
如果级别相同,哪一个先写依赖哪一个,那么我们看一下这个情况:
我们现在将user-log和user-core的依赖先后调换一下:
首先看我们的log4j,使用的就是1.2.17了:
这一点是没有问题的,但是看我们的common-logging版本:
是1.1.1对吧?回来看一下我们user-core和user-log的common-logging版本:
我们打开user-core的pom的依赖级层图:
发现user-core的common-logging是间接依赖,也就是说是dbunit使用的common-logging。
而我们看一下user-log的common-logging的依赖关系:
发现是直接依赖关系。
所以,当依赖级别相同的时候,相同的jar,我们是哪个先被依赖就依赖那个模块的jar,前提是,此jar我们只依赖它“依赖层数”最短的jar。
这就是为什么会使用common-logging的1.1.1版本。
能不能限制某些依赖的使用呢?假设我们就想用common-logging的1.0.4版本,我们可在user-service的pom文件中这样修改:
这样就排除使用user-log的commons-logging包了,我们再看user-service的依赖,发现已经变成1.0.4版本:
所以,当依赖冲突的时候,我们可以通过exclusion排除包来解决依赖的冲突。
转载请注明出处:http://blog.csdn.net/acmman/article/details/50628499