Maven企业级应用(四) 之依赖管理机制

1、依赖引入的方式

可以用如下方式引入依赖

<dependency>
	<groupId></groupId>
	<artifactId></artifactId>
	<version></version>
	<type></type>
	<scope></scope>
	<optional></optional>
</dependency>

那么问题来了,比如感觉自己可能需要一个什么东西,怎么知道要引入哪些依赖呢?

  1. 如果是要用某个比较重要的技术,比如elasticsearch,spring,mybatis,等等,开源项目,直接到官网里面去,里面会告诉你如何在java里面引入maven依赖
  2. 另外可能在开发的过程中,也许还需要一些小依赖,比如log4j,slf4j,jackson,mysql connector驱动等,甚至连官网都不用去了,直接百度。
    百度:maven + 你需要的依赖名称,比如log4j

下面两个方式,走国外的网站去搜索,速度较慢
sonatype nexus:http://repository.sonatype.org
mvnbrowser:http://www.mvnbrowser.com

2、依赖声明的三要素,坐标

groupId、artifactId、version,就够了,type很少用
声明了三要素,一个坐标唯一定位了一个依赖的某个版本的jar包,maven会自动到远程的中央仓库里面去,给我们去找,下载到本地来,在打包的时候,就会自动使用。

3、依赖范围

<scope></scope>

maven有三套classpath,classpath就是项目中用到的各种依赖的路径,jvm在运行的时候需要去classpath下面加载对应的类

maven在编译源代码的时候有一套classpath;在编译测试代码以及执行测试代码的时候,有一套classpath;运行项目的时候,有一套classpath;依赖范围会控制依赖包与这三种classpath的关系。

简单来说,不同的依赖范围,会导致那个依赖包可能在编译、测试或者打包运行的时候,有时候可以使用,有时候不能够使用。

  1. compile:默认的范围。对编译、测试和运行的classpath都有效。一般都是用这种scope
  2. test:仅仅对于编译以及运行测试代码的classpath有效,编译或者运行主代码的时候无效,仅仅测试代码需要用的依赖一般都会设置为这个范围,比如junit。一些测试框架,或者只有在测试代码中才会使用的一些依赖,会设置为test。这个的好处在于,在打包的时候这种test scope的依赖是不会放到最终的发布包里去的从而减少了发布包的体积。
  3. provided:编译和测试的时候有效,但是在运行的时候无效,因为可能环境已经提供了。比如servlet-api,一般就是这个范围,在运行的时候,servlet容器会提供依赖。servlet-api是用来开发java web项目的,可能你在开发代码和执行单元测试的时候,需要在pom.xml里面声明这个servlet-api的依赖,因为要写代码和测试代码。但是最终打完包之后,放到tomcat容器里面去跑的时候,是不需要将这个servlet-api的依赖包打入发布包中的,因为tomcat容器本身就会给你提供servlet-api的包。
  4. runtime:测试和运行classpath有效,但是编译代码时无效,比如jdbc的驱动实现类,比如mysql驱动。因为写代码的时候是基于javax.sql包下的标准接口去写代码的。只有在测试和实际运行的时候需要用这个包,但是编译的时候只要javax.sql接口就可以了,不需要mysql驱动类。一般我们声明mysql驱动的时候,不会设置为runtime,因为也许你开发代码的时候会用到mysql驱动特定的api接口,不仅仅只是用javax.sql。

4、传递性依赖

由于有的依赖可能有其他的依赖,其他的依赖也可能有依赖,以此类推。在纯手工时期,我们可能只加了第一层依赖,运行报错后接着加入第二层依赖,以此类推,这样极其麻烦。
maven的传递性依赖,是指maven自动递归解析所有的依赖,然后负责将依赖下载下来。所有层级的依赖,都会成为项目的依赖,不需要我们手工干预。不管有多少层级。所有的依赖都会下载下来。
比如我们的项目依赖了junit, junit又依赖了A,A又依赖了B。此时如果我们的项目对junit的依赖范围是test,junit对A的依赖范围为compile,那么我们的项目对A的依赖范围为test。
具体情况如下表:第一列是一级依赖,第一行是二级依赖

compiletestprovidedruntime
compilecompileruntime
testtesttest
providedprovidedprovidedprovided
runtimeruntimeruntime

有可能依赖是不会传递的,就是可能有些多层级的依赖,是不会成为我们项目的依赖的。
比如说我们的项目依赖A,范围是compile。A又依赖B,范围是test。此时我们的项目是不会依赖B,因为A只有在测试的时候才会用到B,我们的项目依赖A是生产用的,我们去依赖B干嘛呢?B是给A测试的。

5、依赖调解

maven会自动解析所有层级的依赖,给我们自动下载所有的依赖,但是也可能会出现依赖冲突的问题

比如A->B->C->X(1.0),A->D->X(2.0),A有两个传递性依赖X,不同的版本。此时就产生了依赖冲突的问题,那么maven就会用依赖调解的机制来解决这种问题。此时就会依赖调解,采用就近原则,离A最近的选用,就是X的2.0版本。
如果A->B->X(1.0)和A->D->X(2.0),路径等长呢?那么此时maven会选择第一声明原则,哪个依赖在pom.xml里先声明,就用哪个。

6、可选依赖

<optional>true</optional>

此时依赖传递失效,不会向上传递

如果A依赖于B,B依赖于C,B对C的依赖是optional,那么A就不会依赖于C。反之,如果没有optional,根据传递性依赖机制,A会依赖于C。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值