Maven教程(五)坐标的概念以及依赖管理

1、什么是坐标?

①、数学中的坐标

在平面上,使用 X 、Y 两个向量可以唯一的定位平面中的任何一个点

在空间中,使用 X、Y、Z 三个向量可以唯一的定位空间中的任意一个点

②、Maven 中的坐标

俗称 gav:使用下面三个向量子仓库中唯一定位一个 Maven 工程

在项目中的 pom.xml 文件中,我们可以看到下面gav的定义:

1、groupid:公司或组织域名倒序

<groupid>com.ys.maven</groupid>

2、artifactid:模块名,也是实际项目的名称

<artifactid>Maven_05</artifactid>

3、version:当前项目的版本

<version>0.0.1-SNAPSHOT</version>

③、Maven 坐标和仓库,jar 包的关系

什么是仓库,后面我们会详细讲解,现在你只需要知道是Maven 用来存放 jar 包的地方。

那么依照上面定义的 gav,我们执行 mvn -install 命令,会出现什么情况呢?

首先进入通过 settings.xml 文件配置的仓库目录。

将我们上面配置的 gav 向量组合起来就是目录:

com/ys/maven/Maven_05/0.0.1-SNAPSHOT/Maven_05-0.0.1-SNAPSHOT.jar

其次,我们观察打出来的 jar 包:

Maven_05-0.0.1-SNAPSHOT.jar

也就是 artifactid-version.jar

2、什么是依赖?

什么是 依赖?相信有过一定开发经验的人知道,每当我们需要使用某个框架时,比如 SpringMVC,那么我们需要导入相应的 jar 包,但是手动导入包的时候,往往会漏掉几个 jar 包,那么在使用该框架的时候系统就会报错。那么我们就说导入的包与未导入的包存在依赖关系。而使用 Maven,我们只需要在 pom.xml 文件中进行相应的配置,它就会帮助我们自动管理 jar 包之间的依赖关系。那么它是怎么管理的呢,接下来我们会详细讲解。

3、依赖的详细配置

我们以 Junit 为例,在 pom.xml 文件中进行详细而完整的配置。

<project>     
    <dependencies>
        <dependency>
            <groupId>junit</groupId>     
            <artifactId>junit</artifactId>     
            <version>3.8.1</version>
            <type>...</type>
            <scope>...</scope>
            <optional>...</optional>
            <exclusions>     
                <exclusion>     
                  <groupId>...</groupId>     
                  <artifactId>...</artifactId>     
                </exclusion>
          </exclusions>     
        </dependency>        
      </dependencies>     
</project>

①、dependencies:一个 pom.xml 文件中只能存在一个这样的标签。用来管理依赖的总标签。

②、dependency:包含在dependencies标签中,可以有无数个,每一个表示一个依赖

③、groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。

④、type:依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar。

⑤、scope:依赖的范围,默认值是 compile。后面会进行详解。

⑥、optional:标记依赖是否可选。

⑦、exclusions:用来排除传递性依赖,后面会进行详细介绍。

4、依赖的范围 scope

一般情况下,我们对前面三个依赖用的比较多。下面的主程序表示maven 目录结构 src/main/java.测试程序目录结构为:src/test/java

1、compile 范围依赖

对主程序是否有效:有效

对测试程序是否有效:有效

是否参与打包:参与

是否参与部署:参与

典型例子:log4j

2、test 范围依赖

对主程序是否有效:无效

对测试程序是否有效:有效

是否参与打包:不参与

是否参与部署:不参与

典型例子:Junit

3、provided 范围依赖

对主程序是否有效:有效

对测试程序是否有效:有效

是否参与打包:不参与

是否参与部署:不参与

典型例子:servlet-api.jar,一般在发布到 服务器中,比如 tomcat,服务器会自带 servlet-api.jar 包,所以provided 范围依赖只在编译测试有效。

4、runtime 范围依赖:在测试、运行的时候依赖,在编译的时候不依赖。例如:JDBC驱动,项目代码只需要jdk提供的jdbc接口,只有在执行测试和运行项目的时候才需要实现jdbc的功能。

接下来我们举几个例子在工程中实际去理解:

test 依赖和 compile 依赖的区别:

①、首先我们在 pom.xml 文件中配置,Junit 的 test 依赖

②、我们在主程序中去导入 Junit 的包,然后进行 mvn -compile 编译,很明显,test 范围的在主程序中无效,故编译会报错。

我们在 src/main/java 包下新建 MavenTest.java,并导入 Junit 包

然后执行 mvn -compile 操作,如下图报错信息:

③、我们将 Junit 的依赖范围改为 compile,然后执行 mvn -compile

发现 mvn -compile 没有报错了。


4、依赖的传递

比如我们创建三个Maven 工程,maven-first,maven-second以及maven-third,而third依赖于second,second又依赖于first,那么我们说 second 是 third 的第一直接依赖,first是second的第二直接依赖。而first是third的间接依赖。

依赖之间的传递如下图:第一列表示第一直接依赖,第一行表示第二直接依赖

总结:

1、当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。
2、当第二直接依赖的范围是test的时候,依赖不会得以传递。
3、当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided;
4、当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;

我们这里举个例子来看:

①、第二依赖范围是 test

Maven_first 的pom.xml 文件如下:

然后Maven_second依赖Maven_fisrt,Maven_third依赖Maven-second,其pom.xml 文件如下:

Maven_second的 pom.xml

Maven_third的 pom.xml

我们发现在 Maven_third和 Maven_second 都没有 Maven_first 引入的 Junit 包,正好符合上面总结的第二点:当第二直接依赖的范围是test的时候,依赖不会得以传递。

②、第二依赖范围是 compile

如果我们将 Maven_first 的Junit 改为 compile,那么将会符合上面总结的第一点:当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。

5、依赖的排除

如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会自动将 A 依赖的 B 引入当前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。

比如:我们在Maven_first 中添加 spring-core,maven 会自动将 commons-logging添加进来,那么由于 Maven_second 是依赖 Maven_first 的,那么 Maven_second 中将存在 spring-core(自带了commons-logging),这时候我们不想要 commons-logging,那该怎么办呢?我们上面第二大点提到了:

exclusions:用来排除传递性依赖

Maven_first 的 pom.xml 文件

由于 Maven_second 依赖 Maven_second,故Maven_second 存在 spring-core 包

如何排除呢?我们在 Maven_second 的 pom.xml 文件中添加如下代码:

再次查看工程:Maven_second 的 commons-logging 已经移除了

6、依赖的冲突

在maven中存在两种冲突方式:一种是跨pom文件的冲突,一致是同一个pom文件中的冲突。

①、跨 pom 文件,路径最短者优先。比如我们在 Maven_first 中的 Junit 是4.9版本的,Maven_second 中的 Junit 是4.8版本的,那么Maven_third 中的 Junit 将会是那个版本呢?

由上图我们可以看出,由于 Maven_second 是 Maven_third 的直接依赖,明显相比于 Maven_first 路径要短,所以 Maven_third 的 Junit 版本与 Maven_second 保持一致。

②、同一个pom.xml 文件,先申明者优先。

看 Maven_second

7、可选依赖

Optional标签标示该依赖是否可选,默认是false。可以理解为,如果为true,则表示该依赖不会传递下去,如果为false,则会传递下去。

我们是在 Maven_second 的 pom 文件中设定 Junit 不可传递,那么Maven_third 工程中将不会有来自 Maven_second 的 Junit 的传递。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,490评论 18 139
  • 简介 概述 Maven 是一个项目管理和整合工具 Maven 为开发者提供了一套完整的构建生命周期框架 Maven...
    闽越布衣阅读 4,252评论 6 39
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,678评论 6 342
  • Maven的基本了解 什么是Maven? Maven就是Apache下的一个开源项目。它是用纯java开发的。是一...
    Bcome阅读 2,738评论 0 7
  • 一、Maven坐标和仓库   Maven坐标是一个唯一的标识,用于表示我们的项目的一些信息或者引用jar包的位置。...
    嗷老板阅读 786评论 0 5