Maven学习笔记(二):Maven依赖

依赖是Maven中最关键的部分,使用Maven管理项目很大的原因是因为他的依赖管理功能。

全部章节传送门:
Maven学习笔记(一):Maven概述
Maven学习笔记(二):Maven依赖
Maven学习笔记(三):POM文件
Maven学习笔记(四):Maven仓库
Maven学习笔记(五):Maven插件

在工程中引入某个jar包,只需要在pom.xml中引入jar包的坐标,比如引入log4j的依赖:

<dependencies>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

Maven通过groupId、artifactId与version三个向量来定位Maven仓库其jar包所在的位置,并把对应的jar包引入到工程中来。

依赖范围

maven 项目不同的阶段引入到classpath中的依赖是不同的,例如,编译时,maven 会将与编译相关的依赖引入classpath中,测试时,maven会将测试相关的的依赖引入到classpath中,运行时,maven会将与运行相关的依赖引入classpath中,而依赖范围就是用来控制依赖于这三种classpath的关系。

前面的例子中,scope标签就是依赖范围的配置。该项默认配置compile,可选配置还有test、provided、runtime、system、import,其中compile、test和provided使用较多,下面依次介绍。

编译依赖范围(compile)

该范围就是默认依赖范围,此依赖范围对于编译、测试、运行三种classpath都有效,举个简单的例子,假如项目中有spring-core的依赖,那么spring-core不管是在编译,测试,还是运行都会被用到,因此spring-core必须是编译范围(构件默认的是编译范围,所以依赖范围是编译范围的无须显示指定)

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>2.5</version>
    <scope>compile</scope> <!--默认为该依赖范围,无须显示指定-->
</dependency>

测试依赖范围(test)

使用此依赖范围的依赖,只对测试classpath有效,在编译主代码和项目运行时,都将无法使用该依赖,最典型的例子就是 Junit, 构件在测试时才需要,所以它的依赖范围是测试,因此它的依赖范围需要显示指定为<scope>test</scope>,当然不显示指定依赖范围也不会报错,但是该依赖会被加入到编译和运行的classpath中,造成不必要的浪费 。

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.7</version>
    <scope>test</scope>
</dependency>

已提供依赖范围(provided)

使用该依赖范围的maven依赖,只对编译和测试的classpath有效,对运行的classpath无效,典型的例子就是servlet-api, 编译和测试该项目的时候需要该依赖,但是在运行时,web容器已经提供的该依赖,所以运行时就不再需要此依赖,如果不显示指定该依赖范围,并且容器依赖的版本和maven依赖的版本不一致的话,可能会引起版本冲突,造成不良影响。

<dependency>
    <groupId>javax-servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
</dependency>

运行时依赖范围(runtime)

使用该依赖范围的maven依赖,只对测试和运行的classpath有效,对编译的classpath无效,典型例子就是JDBC的驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动。

系统依赖范围(system)

该依赖与classpath的关系与provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可移植,因此谨慎使用,systemPath元素可以引用环境变量:

<dependency>
    <groupId>javax.sql</groupId>
    <artifactId>jdbc-stext</artifactId>
    <version>2.0</version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath> 
</dependency>

导入依赖范围(import)

该依赖范围不会对三种classpath产生影响,该依赖范围只能与dependencyManagement元素配合使用,其功能为将目标pom文件中dependencyManagement的配置导入合并到当前pom的dependencyManagement中。有关dependencyManagement的功能会在Maven继承特性部分说明。

依赖的传递

依赖的传递性指:在A中添加对B的依赖,在B中添加对C的依赖,如果依赖范围是compile的,A不仅会有B的jar 包,也会有C的jar 包。如果在C中添加了某个依赖,那么根据传递性,A和B也可以使用C添加的依赖,而不需要自己再重新引入依赖。

依赖传递的原则:

  • 最短路径优先原则:如果A依赖于B,B依赖于C,在B和C 中同时有log4j的依赖,并且这两个版本不一致,那么A会根据最短路径原则,在A中会传递过来B的log4j版本。
  • 路径相同先声明原则:如果在A同时依赖于B和C,B和C没有依赖关系,并且都有log4j的依赖,且版本不一致,那么A会引入在pom.xml中先声明依赖的log4j版本。

依赖的排除

我们在当前工程中引入了A的依赖,而A同时有对B的依赖,根据传递性我们知道,在当前工程中会自动引入对B的依赖。如果我们不想引入对B的依赖,我们就需要在引入对A依赖的同时排除对B的依赖。

下面我们以spring-core为例,当我们在pom.xml中引入对spring-core 的同时,会自动将commons-logging 的jar 包引入进来,如果我们不想引入commons-logging,就可以进行如下配置:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.14.RELEASE</version>

        <exclusions>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exlcusion>
        </exclusions>
    </dependency>
</dependencies>

聚合和继承

将多个项目同时运行就称为聚合。只需在pom文件中作如下配置即可实现聚合:

<modules>
    <module>web-connection-pool</module>
    <module>web-java-crawler</module>
</modules>

另外,聚合模块的打包方式必须为pom,否则无法完成构建

在聚合多个项目时,如果这些被聚合的项目中需要引入相同的Jar,那么可以将这些Jar写入父pom中,各个子项目继承该pom即可。,父模块的打包方式必须为pom,否则无法构建项目。

通过在各个子模块中配置来表明其继承与哪一个父模块:

<parent>
   <groupId>com.baidu</groupId>
   <artifactId>miliao-rootpom</artifactId> 
   <version>2.0.3</version>
</parent>

继承的POM元素如下:

  • groupId:项目组ID,项目坐标的核心元素
  • version:项目版本,项目坐标的核心因素
  • description:项目的描述信息
  • organization:项目的组织信息
  • inceptionYear:项目的创始年份
  • url:项目的URL地址
  • developers:项目的开发者信息
  • contributors:项目的贡献者信息
  • distributionManagement:项目的部署配置
  • issueManagement:项目的缺陷跟踪系统信息
  • ciManagement:项目的持续集成系统信息
  • scm:项目的版本控制系统
  • malilingLists:项目的邮件列表信息
  • properties:自定义的Maven属性
  • dependencies:项目的依赖配置
  • dependencyManagement:项目的依赖管理配置
  • repositories:项目的仓库配置
  • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
  • reporting:包括项目的报告输出目录配置、报告插件配置等
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • Maven的基本了解 什么是Maven? Maven就是Apache下的一个开源项目。它是用纯java开发的。是一...
    Bcome阅读 2,763评论 0 7
  • 一、maven的两个作用 项目自动化构建,通过命令行就可以完成整个项目构建过程,不需要我们手动地进行项目构建 管理...
    lifeline张阅读 831评论 0 1
  • maven项目中需要使用到其它依赖时,则需要在pom.xml中配置<dependency>元素也就是依赖声明,这样...
    zlcook阅读 1,791评论 1 3
  • 祝福你这双脚,愿他们在幼年时就学会跟从,因为紧紧跟从,而熟悉每条正路的走法。 祝福你的双脚,自幼年便懂得闪躲路上的...
    未完成的作品阅读 296评论 1 0
  • 小时候,我们一起爬山、一起捉迷藏、一起捣蛋,我们青梅竹马,认识已有十三年了。不知道从什么时候开始,慢慢的喜欢上他了...
    印跡阅读 167评论 0 0