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. 转 spring官方文档中文版

    转 http://blog.csdn.net/tangtong1/article/details/51326887另附码云地址 https://gitee.com/free/spring-framew ...

  2. linux 系统下MySQL5.7重置root密码(完整版,含ERROR 1820 (HY000)解决方案)

    mysql的root密码忘记了怎么重置? 往下看: 1.保证你的mysql服务处于关闭状态.(用ps -ef | grep mysql 查看进程,有则kill -9 进程号) 2.在my.cnf所在目 ...

  3. SpringBoot整合Quartz

    1.引入quzrtz <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId> ...

  4. spring过滤器和拦截器的区别和联系

    一 简介 (1)过滤器: 依赖于servlet容器,是JavaEE标准,是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理.在实现上基于函数回调,可 ...

  5. linux跨主机复制文件

    scp -r billing@10.200.171.111:/billdata2/user/yanhm/redis/* /newboss/billing/user/aabb 其中: 10.200.17 ...

  6. java代码格式化

    Java source formatting You are probably familiar with the Eclipse hotkeys to automatically format yo ...

  7. 学习spring in action 第一天

    这段时间,开始学习java吧,因为C sharp 学习了java的大量语法格式,所以,留意下,就不会错了,java 有的c sharp也有,而且之前我也学习过java的桌面开发,但是一下子上来就要自己 ...

  8. Spring Java-based容器配置(二)

    组装Java-based的配置 使用@Import注解 跟在Spring XML文件里使用<import>元素加入模块化的配置相似,@Import注解同意你载入其它配置类中的@Bean定义 ...

  9. (转 )【Android那些高逼格的写法】InvocationHandler与代理模式

    转自这个公众号: 今天会聊一下InvocationHandler.说到InvocationHandler不得不提到的就是代理模式,什么是代理模式,举个例子,你玩游戏,花钱请个代练,代练其实是登录你的账 ...

  10. jvm(12)-java内存模型与线程

    [0]README 0.1)本文部分文字描述转自“深入理解jvm”,旨在学习“java内存模型与线程” 的基础知识:   [1]概述 1)并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律称为计 ...