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. libevent源码学习_event_test

    对应的sample文件中提供了event_test.c,里面就是关于事件的简单示例,具体如下: /* * Compile with: * cc -I/usr/local/include -o even ...

  2. ipk CONTROL 目录的作用

    CONTROL文件夹下的文件意义preinst        - shell script,在ipk包开始安装前执行;postinst       - shell script,在ipk包安装后执行; ...

  3. cmake工程使用distcc

    distcc可以加速编译,但是遇到cmake可能就需要处理下. 问题 distcc在 /usr/lib/distcc 中放了各编译器的soft link(如cc/gcc等等),如果 /usr/lib/ ...

  4. bootstrap-table接合knockout.js

    function responseHandler(data) { if (data.ErrorNo > 0) { return; } var count = data.Data.TotalRow ...

  5. Spark Core源代码分析: RDD基础

    RDD RDD初始參数:上下文和一组依赖 abstract class RDD[T: ClassTag]( @transient private var sc: SparkContext, @tran ...

  6. 基于JS实现回到页面顶部的五种写法(从实现到增强)

    这篇文章主要介绍了基于JS实现回到页面顶部的五种写法(从实现到增强)的相关资料,本文介绍的非常详细,实用性也非常高,非常具有参考借鉴价值,需要的朋友可以参考下   写法 [1]锚点 使用锚点链接是一种 ...

  7. marquee标签跑马灯连续无空白播放效果 纯CSS(chrome opera有效)

    marquee似乎没有设置首尾相连播放的属性,内容滚动时总会留出一段marquee本身长度的空隙,某些情况下很不方便: 捣鼓了一会,得出一种解决办法,关键有两点: 1.将需要滚动的内容复制一份于同一行 ...

  8. java 定时器

    import java.io.IOException; import java.util.Timer; public class TimerTest { public static void main ...

  9. libsvm以概率输出单个test样例的判别结果

    在函数svmtrain和svmpredict的输入参数部分加入'-b 1'比如原先是 svmtrain -c 8.0 -g 0.0078125 a1a.scale 修改过后就是 svmtrain -b ...

  10. Webkit内核探究【2】——css简介

    注:[转载请注明文章来源.保持原样] 出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660364.html 作者:李嘉昱 CSS在Webkit中 ...