Maven的坐标和依赖

1 Maven坐标

1.1 什么是Maven坐标

Maven坐标:世界上任何一组构件都可以使用Maven坐标来唯一标识,Maven坐标的元素包括groupId、artifactId、version、packaging、classifier。只要我们提供正确的坐标元素,Maven就能找到对应的构件。

那么Maven是从哪里下载构件的呢?

答案其实很简单,Maven内置了一个中央仓库的地址,该中央仓库包含了世界上大部分流行的开源项目构件,Maven会在需要的时候去那里下载。

在我们开发自己项目的时候,也需要为其定义适当的坐标,这是Maven强制要求的。在这个基础上,其他Maven项目才能引用该项目生成的构件。

1.2 坐标元素详解

  • groupId:定义了当前Maven项目隶属于的公司组织和实际项目。groupId的表示方式与Java包名的表示方式类似,通常用域名反向一一对应,比如有一个Maven项目隶属于mycom公司的myapp项目,那么groupId就应该是com.mycom.myapp。
  • artifactId:定义了实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀,这样做的好处是便于寻找构件。因为默认情况下,Maven生成的构件,其文件名会以artifactId作为开头,比如myapp-core.1.0.0.jar,使用实际项目名称作为前缀后,就能方便的从一个lib文件夹中找到某个项目的一组构件。
  • version:定义了Maven项目当前所处的版本。需要注意的是Maven定义了一整套版本规范,以及快照(SNAPSHOT)的概念,以后会详细介绍。
  • packaging:定义了Maven项目的打包方式。默认是jar。
  • classifier:定义了帮助定义构建输出的一些附属构件。

上述5个元素中,groupId、artifactId、version是必须定义的,packaging是可选的,而classifier是不能直接定义的。

2 Maven依赖

2.1 依赖的配置

一个依赖的声明可以包含如下的元素:

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

根元素project下的dependencies可以包含一个或多个dependency元素,用来声明一个或者多个项目依赖。每个依赖可以包含的元素有:

  • groupId、artifactId和version:依赖的基本坐标,这是最重要的,通过基本坐标Maven才能找到需要的依赖。
  • type:依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值为jar。
  • scope:依赖范围,见2.2。
  • optional:标记依赖是否可选,见2.6。
  • exclusions:用来排除传递性依赖,见2.。

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

2.2 依赖范围

Maven因为执行一系列编译、测试和部署运行等操作,在不同的操作下使用的classpath不同,依赖范围就是用来控制依赖与三种 classpath(编译classpath、测试classpath、运行classpath)的关系,Maven有以下几种依赖范围:

  • compile:编译依赖范围(默认依赖范围),使用此依赖范围对于编译、测试、运行三种 classpath 都有效,即在编译、测试和运行的时候都要使用该依赖jar包。
  • test:测试依赖范围,从字面意思就可以知道此依赖范围只能用于测试classpath,而在编译和运行项目时无法使用此类依赖,典型的是JUnit,它只用于编译测试代码和运行测试代码的时候才需要。
  • provided:已提供依赖范围,对于编译和测试classpath有效,而对运行时classpath无效,比如:servlet-api,因为servlet-api,tomcat等web服务器中已经存在,如果再打包进去,那么包之间就会冲突。
  • runtime:运行时依赖范围,对于测试和运行classpath有效,但是在编译主代码时无效,典型的就是JDBC驱动实现。
  • system:系统依赖范围,使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径,不依赖Maven仓库解析,并且往往与本机绑定,所以可能会造成建构的不可移植,谨慎使用。

依赖范围与classpath的关系:

2.3 传递性依赖

假设有如下依赖关系:

A->B(compile)     第一关系: a依赖b   compile

B->C(compile)     第二关系: b依赖c   compile

当在A中配置

<dependency>
<groupId>com.B</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
</dependency>

则A中会自动导入C包。

有了传递性依赖机制,Maven会解析各个直接依赖的pom,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。

2.4 传递性依赖和依赖范围

假设A依赖B,B依赖C,那么A对于B是第一直接依赖,B对C是第二直接依赖,A对C是传递性依赖。

第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围,如下表:

2.5 依赖调解

Maven依赖调解的第一原则是:路径最近者优先。

Maven依赖调解的第二原则是:第一声明者优先。

例1:

A->B->C->X(1.0)

A->D->X(2.0)

此时Maven按照最短路径选择导入x(2.0)。

例2:

A->B->X(1.0)

A->D->X(2.0)

路径长度一致,则优先选择第一个声明的依赖,此时导入x(1.0)。

2.6 可选依赖

在声明依赖时,使用<optional>元素表示依赖为可选依赖。

<optional>true</optional>

可选依赖作用:

如果存在依赖A->B、B->X(可选)、B->Y(可选)。如果这三个依赖都是compile的,X、Y就是A的传递性依赖,但是当X、Y是可选依赖时,X、Y将不会成为A的依赖。

2.7 排除依赖

当A->B->C(1.0)时,此时在A项目中,如不想使用C(1.0),而使用C(2.0),则需要使用exclusion排除B对C(1.0)的依赖。并在A中引入C(2.0)。

<!--排除B对C的依赖-->
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>0.1</version>
<exclusions>
<exclusion>
<groupId>C</groupId>
<artifactId>C</artifactId><!--无需指定要排除项目的版本号-->
</exclusion>
</exclusions>
</dependency> <!---在A中引入C(2.0)-->
<dependency>
<groupId>C</groupId>
<artifactId>C</artifactId>
<version>2.0</version>
</dependency>

2.8 归类依赖

假如我们依赖spring的jar包,有好几个但是版本是一致的,如果升级的时候一起升级,版本统一管理更好。
    <properties>
<org.springframework-version>4.0.0.RELEASE</org.springframework-version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework-version}</version>
</dependency>

2.9 依赖关系的查看

Maven会自动解析所有项目的直接依赖和传递性依赖,并且根据规则正确判断每个依赖的范围,对于一些依赖冲突,也能进行调节,以确保任何一个构件只有唯一的版本在依赖中存在,这些工作之后,最后得到那些依赖被称为已解析依赖

cmd进入工程根目录,执行mvn命令:

  • mvn dependency:list 查看当前项目的已解析依赖
  • mvn dependency:tree 查看当前项目依赖树
  • mvn dependency:analyze 分析依赖关系

参考:

《Maven实战》

Maven坐标和依赖

Maven依赖范围及依赖传递

Maven学习笔记—坐标和依赖的更多相关文章

  1. Maven学习笔记—仓库

    Maven仓库 1 什么是Maven仓库 在Maven中,任何一个依赖.插件或者项目构建的输出,都可以成为构件,而Maven通常在某个位置统一的存储所有Maven项目共享的构件,这个统一的位置就是Ma ...

  2. MAVEN学习笔记之Maven插件的应用(4)

    MAVEN学习笔记之Maven插件的应用(4) <build> <pluginManagement> <plugins> <plugin> <gr ...

  3. MAVEN学习笔记之Maven生命周期和插件简介(3)

    MAVEN学习笔记之Maven生命周期和插件简介(3) clean compile site三套生命周期相互独立. clean pre-clean 执行清理前的工作 clean 清理上一次构建生成的所 ...

  4. MAVEN学习笔记之基础(1)

    MAVEN学习笔记之基础(1) 0.0 maven文件结构 pom.xml src main java package resource test java package resource targ ...

  5. Maven 学习笔记(二)

    前面一文——Maven 学习笔记(一)中已经提到了 pom 的大部分配置,Maven 本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给创建来完成,每一个任务都会对应一个插件 ...

  6. Maven学习笔记-03-Eclipse下maven项目在Tomcat7和Jetty6中部署调试

    现在最新的Eclipse Luna Release 已经内置了Maven插件,这让我们的工作简洁了不少,只要把项目直接导入就可以,不用考虑插件什么的问题,但是导入之后的项目既可以部署在Tomcat也可 ...

  7. .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]

    原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...

  8. .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]

    原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...

  9. .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]

    为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...

随机推荐

  1. js将用户上传gif动图分解成多张帧图片

    js将用户上传gif动图分解成多张帧图片 写在前面 工作中遇到一个这么一个需求:这是一个多图上传的场景,如果用户上传选择多张图片,则上传后直接展示多张图片,如果上传的图片是gif动图,则需要分解这张动 ...

  2. std::vector

    Vector Vectors are sequence containers representing arrays that can change in size. Just like arrays ...

  3. 使用wget工具抓取网页和图片 成功尝试

    使用wget工具抓取网页和图片 发表于1年前(2014-12-17 11:29)   阅读(2471) | 评论(14) 85人收藏此文章, 我要收藏 赞7 wget 网页抓取 图片抓取 目录[-] ...

  4. request:getParameter和getAttribute区别

    getParameter 是用来接受用post个get方法传递过来的参数的.getAttribute 必须先setAttribute.(1)request.getParameter() 取得是通过容器 ...

  5. Web services 有两种类型的应用

    可重复使用的应用程序组件 有一些功能是不同的应用程序常常会用到的.那么为什么要周而复始地开发它们呢? Web services 可以把应用程序组件作为服务来提供,比如汇率转换.天气预报或者甚至是语言翻 ...

  6. Eclipse 任务管理

    管理任务 在Eclipse中用TODO标签管理任务,利用这个功能可以方便地将项目中一些需要处理的任务记录下来. 我们可以在 Java 代码中的注释添加 TODO 单词来标记一个任务,任务可以通过 Ta ...

  7. python 爬虫实战1 爬取糗事百科段子

    首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 本篇目标 抓取糗事百科热门段子 过滤带有图片的段子 实现每按一次回车显示一个段子的发布时间,发布人 ...

  8. MySQL的语法高级之SELECT

    1.语法:select 字段列表 from  子句 [where 子句][group by 子句][ order by 子句][having 子句][limit 子句]; 注解: 1.where子句对 ...

  9. [网络通信] OSI七层模型思维导图

    ISO:国际标准化组织:OSI:开放系统互联 (部分描述不准确和不详细)

  10. Splitting Pile

    Splitting Pile Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement Snuke a ...