Maven坐标与依赖

最近想深度学习下maven,找到一本书叫《Maven实战》,这本书讲的确实很好,唯一遗憾的是当时maven教学版本是3.0.0的,而目前已经到了3.5.4了,版本存在差距,

没关系,如果有时间和精力我也会阅读官方文档,看看到底有哪些变换。

一、坐标详解

1、何为Maven坐标

maven定义了这样一组规则:世界上任何一个构件都可以使用maven坐标唯一标识,坐标元素包括:groupId、artifactId、version、packaging、classifier。只要提供正确

的坐标就能从仓库中找到相应的构件供我们使用。maven从哪里下载构件呢?答:maven内置了一个中央仓库的地址,该中央仓库包含了世界上大部分流行的开源构件。

2、坐标详解

任何构件都必须明确定义自己的坐标,而一组maven坐标是通过一些元素定义的,他们是:groupId、artifactId、version、packaging、classifier。先看一组坐标定义如下

 <groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>

这是nexus-indexer项目的坐标,nexus-indexer是一个对maven仓库编纂索引并提供搜索功能的类库,它是Nexus项目的一个子模块。

goupId: 定义了当前maven项目隶属的实际项目,一般是域名+项目名。比如:com.alibaba.taotao

artifactId:该元素定义实际项目中的一个maven项目(模块,一般推荐项目名+子模块名。比如:taobao-web

version: 定义maven项目当前所处版本。

packaging:定义maven项目的打包方式,默认使用jar。

classifier:该元素用来帮助定义构件输出的一些附属构件。

上述5元素groupId、artifactId、version是必须的,packaging可选,默认jar,classifier不能直接定义。同时,项目构件的文件名是与坐标对应的,

一般的规则为artificatId-version[-classifier].packaging。packing并非一定与构件扩展名对应,比如packing为maven-plugin的构件扩展名为jar。

二、依赖详解

1、依赖的配置

一般的依赖只有基本的 groupId,artifactId,version。我们来看下详细的依赖配置

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

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

         type:依赖的类型,对于项目坐标定义的packing,大部分情况是不必声明,默认是jar。

      scope :依赖的范围 下面具体讲解

    optional: 标记依赖是否可选,值为true或false,默认为false, 如果为可选依赖,则依赖不具有传递性。即B->X(可选依赖),A->B。此时A的依赖中不包含X。

exclusions:用来排除传递性依赖。

大部分依赖声明只包含基本坐标,然而在一些特殊情况下,其他元素至关重要。

2、依赖范围scope

classpath:用于指定.class文件存放的位置,类加载器会从该路径中加载所需的.class文件到内存中。maven在编译、执行测试、实际运行有着三套不同的classpath。

编译classpath:编译主代码有效

测试classpath:编译、运行测试代码有效

运行classpath:项目运行时有效

maven的依赖范围

 compile:编译依赖范围。(默认方式),有效范围:编译classpath+测试classpath+运行classpath。

      test:测试依赖范围。有效范围:测试classpath  比如:JUnit,只在测试时使用,在编译主代码和运行时不需要此依赖。

provided:已提供依赖范围。有效范围:编译classpath+测试classpath。

 runtime:运行时依赖范围。有效范围:测试classpath+运行classpath。比如:JDBC驱动实现(mysql-connector-java)。

  system:系统依赖范围。有效范围:编译classpath+测试classpath。使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径,

因为此类依赖不是通过maven仓库解析的,而且往往与本地及其系统绑定,可能造成构建的不可移植,慎用。systemPath元素可以引用环境变量。

<!--你引用本地的jar包,当然只能本地使用了-->
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${JAVA_HOME}/lib/rt.jar</systemPath>
</dependency> <!--你会发现这里这里是test,那么里面有个@Test 注解 只能在test目录下有效,在main目录下该注解是无效的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

3、传递依赖性

假设A依赖B,B依赖C,则A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。

如下表,最左边是第一直接依赖范围,上面是第二直接依赖范围,中间交叉单元格表示传递性依赖范围。

规律:

第二直接依赖范围是compile时,传递依赖的范围与第一直接依赖范围一致。

第二直接依赖范围是test时,依赖不会传递。

第二直接依赖范围是provided时,只传递第一直接依赖为provided的依赖。

第二直接依赖范围是runtime时,传递依赖的范围与第一直接依赖范围一致,但是compile例外,此时传递依赖范围为runtime。

4、依赖调节

Maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部 分情况下我们只需要关心项0的直接依赖是什么,而不用考虑这些直接依赖会引人什么传 递性依赖。

但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依 赖是从哪条依赖路径引入的。

例如,项目A有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0),X是A的 传递性依赖,但是两条依赖路径上有两个版本的X,那么哪个X会被Maven解析使用呢?

两个版本都被解析显然是不对的,因为那会造成依赖重复,因此必须选择一个。Maven依 赖调解(Dependency Mediation)的第一原则是:

路径最近者优先。该例中X( 1.0)的路径氏 度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解折使用。

依赖调解第一原则不能解决所有问题,比如这样的依赖关系:A->B->Y(1.0)、A-> C->Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。Maven定义了依赖调解的第二原则:

第一声明者优先。在依 赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最前的那个依赖优胜。该例中,如果B的依赖声明在C之前,那么Y (1.0)就会被解析使用.

5、排除依赖

传递性依赖会给项目引入很多依赖,简化项目依赖管理,但是也会带来问题。

需求:比如当前项目有一个第三方依赖,而第三方依赖依赖了另一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,而SNAPSHOT的不稳定性会直接影响到当前项目。

这时候就应该排除掉SNAPSHOT。并且声明该类库的正式发布版本。

       <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>3.6.10.Final</version>
<exclusions>
<exclusion>
<groupId>slf4j-api</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>

上述代码中hibernate-validator依赖slf4j-api,但是当前项目不想使用传递过来的slf4j-api,所以通过exclusions声明排除依赖。当前项目声明了自己需要的1.7.12版本的slf4j-api。

exclusions可以包含一个或者多fexdWon子元素,因此可以排除一个或者多 个传递性依赖。需要注意的是,声明exclusion的时候只需要groupld和artifactld,而不 笛要version元素,

这是因为只需要gmupkl和arlifactid就能唯一定位依赖图中的某个依 赖。换句话说,Maven解析后的依赖中,不可能出现groupW和artifactld相同,但是 version不同的两个依赖。

注意:排除依赖的时候也要注意,比如A依赖1.1版本的B, ,而你不想要1.1版本的B,而是要2.1的B,这个时候也需要考虑A跟2.1的B是否能兼容。

6、归类依赖

需求:关于springframework的依赖有好多,org.springframework:spirng-core:2.5.6、org.springframework:sprng-beans:2.5.6、org.springframework:spring-context:2.5.6,

他们来自同一个项目不同模块,因此版本都是相同的,可以预见在升级spring时这些依赖都会一起升级,为了方便统一所以使用properties元素定义maven属性。

<project>
....
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springframework.version>4.3.2.RELEASE</springframework.version>
</properties> <!--通过使用${springframework.version}替换掉实际值,将所有spring依赖的版本值都使用这一引用值表示。-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
...
</project>

参考

《Maven实战》. 许晓斌

同时很高兴,找到看过这本书的人的总结。

坐标详解:https://www.jianshu.com/p/30ece967dccd
依赖配置:https://www.jianshu.com/p/79cf4423281a

我只是偶尔安静下来,对过去的种种思忖一番。那些曾经的旧时光里即便有过天真愚钝,也不值得谴责。毕竟,往后的日子,还很长。不断鼓励自己,

天一亮,又是崭新的起点,又是未知的征程(上校20)

【Maven】---坐标与依赖的更多相关文章

  1. 03 Maven 坐标与依赖

    Maven 坐标与依赖 Maven 的一大功能是管理项目依赖.为了能自动化地解析任何一个 Java 构件, Maven 就必须将它们唯一标识,这就依赖管理的底层基础 一一 坐标.本章将详细分析 Mav ...

  2. 4.Maven概念模型,maven的生命周期,Maven坐标,依赖管理(依赖范围,依赖声明),仓库管理,私服概念

     1 maven概念模型 2 maven的生命周期,项目构建过程 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg== ...

  3. 3.Maven坐标和依赖

    1.1 何为Maven坐标 正如之前所说的,Maven的一大功能就是管理项目依赖.为了能自动化地解析任何一个Java构件,Maven就必须将它们唯一标识,这就依赖管理的底层基础——坐标. 1.2 坐标 ...

  4. maven坐标及依赖范围的学习(1)

    首先,我们先了解什么是maven的坐标(重中之重): 在这里我们可以看到那三个红色的行,基本是pom.xml中出现的最多的配置     例如这个配置:这里我们可以看到我们这个项目的pom文件中,他对名 ...

  5. Maven学习笔记—坐标和依赖

    Maven的坐标和依赖 1 Maven坐标 1.1 什么是Maven坐标 Maven坐标:世界上任何一组构件都可以使用Maven坐标来唯一标识,Maven坐标的元素包括groupId.artifact ...

  6. Maven学习(二) -- 坐标和依赖

    标签(空格分隔): 学习笔记 坐标 实际就像在几何中,我们用一对坐标(x, y)来表示坐标系中唯一的点:或者我们可以用(经度,纬度)来表示地球上的某一个位置,在Maven的世界中,有坐标来唯一的表示项 ...

  7. Maven之——坐标和依赖(上)

    Maven之--坐标和依赖(上) 1.    Maven坐标概念 Maven通过构件的坐标来在Maven仓库中定位到详细的构件.Maven的坐标元素包含groupId.artifactId.versi ...

  8. Maven学习笔记2(坐标和依赖)

    1.坐标 Maven坐标为各个构件建立了秩序,任何一个构件都必须明确自己的坐标,一个maven坐标是由一些元素确定的 <groupId>com.alivn.account</grou ...

  9. 《Maven实战》第5章 坐标和依赖

    5.1 Maven坐标——项目唯一标识 groupId(必须定义):定义Mavan项目隶属的实际项目,如SpringFramework,一个实际项目可包含多个Maven项目 artifactId(必须 ...

随机推荐

  1. hbase 问题整理

    阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...

  2. notes for lxf(二)

    函数 abs()绝对值 max()返回最大值 raise 后接异常类 引发异常 函数返回多个值其实就是返回一个tuple 函数默认返回None 如果有必要检查参数类型用isinstance() typ ...

  3. Pandas常用功能总结

    1.读取.csv文件 df2 = pd.read_csv('beijingsale.csv', encoding='gb2312',index_col='id',sep='\t',header=Non ...

  4. Tomcat 配置文件server.xml详解

    前言 Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的 ...

  5. 极简科普 1:什么是 VOIP

    VoIP 的全称是 Voice over Internet Protocol.简单说,就是用过 IP 网络进行即时的语音/视频通信.注意,这里只强调了在传输过程中有使用 IP 网络,并没有说只通过 I ...

  6. Core Location实现定位

    2013/4/22记录: 注意:如非必要,不应该多次轮询位置信息i 使用时,可根据需要制定精度,通过仔细制定所需的绝对最低精度级别,可以纺织不必要的电池消耗.    导入:CoreLocation.f ...

  7. 练习2-1 Programming in C is fun!

    练习2-1 Programming in C is fun! 一 问题描述 本题要求编写程序,输出一个短句“Programming in C is fun!”. 输入格式: 本题目没有输入. 输出格式 ...

  8. HTML入门11

    在网页中添加矢量图形, 使用矢量图形在很多情况下,效果较好,拥有较小的文件尺寸,高度缩放,下面具体讲解如何在网页中添加矢量图形 位图和矢量图 位图文件包含了每个像素的位置和色彩信息,流行的位图格式包括 ...

  9. Java语法细节 - synchronized和volatile

    目录 synchronized关键字 关键字volatile synchronized关键字 synchronized关键字锁住方法和this的不同之处: public synchronized vo ...

  10. 【原创】XAF 常见错误以及对应解决方法

    1.Appearance Criteria设置错误 Exception occurs while assigning the 'DetailView, ID:xxx_DetailView' view ...