首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Maven学习札记(三)——坐标和依赖

2012-08-27 
Maven学习笔记(三)——坐标和依赖参考书籍Maven实战:可在InfoQ的Minibook出下载相关电子版。一、坐标?maven坐

Maven学习笔记(三)——坐标和依赖

参考书籍Maven实战:可在InfoQ的Minibook出下载相关电子版。


一、坐标

?

maven坐标为各种构件引入了秩序,任何一个构件都必须明确定义自己的坐标,而一组maven坐标是通过一些元素定义的,它们是groupId,artifactId,version,packaging,chassifier。先看一组坐标定义,如下:

?

?

?

    groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,maven根据坐标才能找到需要的依赖。type:依赖的类型,对于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值为jar。scope:依赖的范围。optional:标记依赖是否可选。exclusions:用来排除传递性依赖。
    依赖范围

    举例来说,你开发时需要做测试,你需要依赖于junit的jar,但是部署应用时并不需要它,因为单元测试不会在生产环境上跑,也就是说最终打包的jar或者war不包含junit的jar。又如你开发web程序,你的servlet/jsp进行编译需要依赖于servlet-jsp的标准api(J2EE的jar),但是部署时也是不需要它的,因为你的应用服务器肯定有这些东西。

    因此,Maven考虑了6中可能的scope供选择:

    - compile: 默认的scope。编译、测试、打包全都需要。compile参与依赖传递,就是说,你的项目A依赖于B(依赖scope是compile),项目C依赖于你的项目A,那么C也就依赖于B。

    - provided: 表示JDK或者容器会在Runtime时提供这些(jar),如上面说到的servlet api。provided的东西在编译和测试时会用到,不参与传递依赖。

    - runtime: 表示编译时不需要,但测试和运行时需要,最终打包时会包含进去。

    - test: 只用于测试阶段(测试的编译和测试的运行),典型的就是junit的jar。

    - system: 和provided类似,但要求jar是你的系统里已有的,不会在repository里找,如rt.jar,tools.jar这些。

    - import: 简单的说,你的项目的pom可以继承另一个项目的pom,从而继承了父项目的依赖关系,但是因为之后single inheritance的限制,所以创造了import,使得你可以“导入”或者说“继承”任何一到多个项目的依赖关系。

    如果你要考虑更细一些,你的项目依赖于A(scope1),A依赖于B(scope2),那么你的项目对B的依赖应该算是哪个scope呢?官方文档上有个表格,列举了scope1和scope2的一个矩阵关系(各自都可能是compile/provided/runtime/test),然后最后结果应该是什么。


    依赖的传递性
    传递性依赖:account-mail有一个compile范围的spring-core依赖,spring-core有一个compile范围的commons-logging依赖,那么commons-logging就会成为account-mail的compile范围依赖。
    依赖调解
    maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面大部分情况下我们只需要关心项目直接依赖的是什么,而不用考虑这些依赖会引入什么传递性依赖。但有时候,当传递依赖造成问题的时候,我们需要清楚地知道该传递性依赖是从哪条依赖路径引入的。
    maven依赖调解的两个原则。(1)第一原则是:路径最近者优先。(2)第二原则是:第一声明者优先。在依赖路径长度相等的前提下,在pom依赖声明的顺序决定了谁会解析使用,顺序最靠前的那个依赖优胜。
  • 可选依赖

    假设有这样一个依赖关系,项目A依赖于项目B,项目B依赖于项目X和Y,B对于X和Y的依赖都是可选依赖:A-->B,B-->X(可选),B-->Y(可选)。根据传递性依赖的定义,如果所有这三个依赖的范围都是compile,那么X,Y就是A的compile范围传递性依赖。然而,由于这里X,Y是可选依赖,依赖将不会得以传递。换句话说,X,Y将不会对A有任何影响。

    为什么要使用可选依赖这一特性呢?可能项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用两个特性。比如B是一个持久层隔离工具包,它支持多种数据库,包括MySQL,PostgreSQL等,在构建这个工具包的时候,需要这两种数据库的驱动程序,但在使用这个工具包的时候,只会依赖一个数据库。


    ?

热点排行