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. AudioToolKit的简单介绍及教程

    AudioToolKit的简单介绍及教程 (2013-02-21 09:29:18) 转载▼ 标签: 游戏开发 unity3d教程 unity3d unity it 分类: Unity3d之插件篇 原 ...

  2. [c#.Net] NUnit Test 体验

    NUit Test Adapter 安装,两种方式 第一种:从扩展和更新里搜索nunit,进行下载安装

  3. 如何给unity3d工程加入依赖的android工程

    最近在忙着接平台的事,需要接入各种各样的android平台sdk来发布.在接sdk的时候遇到了这样的一个情况,有点麻烦,所以纪录一下. 有些sdk的接入是提供jar包,这样的可以简单地将jar包制作成 ...

  4. iOS视频压缩存储至本地并上传至服务器

    最近做了一个项目,我把其中的核心功能拿出来和大家分享一下,重点还是自己梳理一下. 这里关于视频转码存储我整理了两个方法,这两个方法都是针对相册内视频进行处理的. 1.该方法没有对视频进行压缩,只是将视 ...

  5. deque双端队列用法

    #include <iostream> #include <cstdio> #include <deque> #include <algorithm> ...

  6. mybatis like用法

    针对不同的数据库,like的用法是不一样的,现在具体来说一下 1,SQL SERVER SELECT * FROM user WHERE name like '%'+#{name}+'%' 2,Ora ...

  7. erlang 洗牌 shuffle

    很简单的一个场景:一副扑克(54张)的乱序洗牌 shuffle_list(List) -> [X || {_, X} <- lists:sort([{random:uniform(), N ...

  8. jetty端口灵活配置方法

    在使用maven开发web项目极大地方便了jar包的依赖,在测试时也可以集成Servlet容器,从启动速度和量级上看,Jetty无疑是不二选择. 如果多个项目同时启动,就会端口冲突了. 一种办法是通过 ...

  9. 转载:DenseNet算法详解

    原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/a ...

  10. ios -为什么用WKWebView加载相同的html文本,有时展示的内容却不一样。

      如图: 红色框部分是WKWebView,左边的是正常显示情况,右边的异常显示.我是在网页加载完成回调里执行的webview高度自适应内容: // 页面加载完成之后调用 - (void)webVie ...