依赖管理是Maven的特性之一,它是用户最为熟悉的特性之一,也是Maven擅长的领域之一。管理单个项目的依赖并没有太大困难,但是当您开始处理由数十或数百个模块组成的多模块项目和应用程序时,Maven可以帮助您在维护高控制程度和稳定性。

依赖的传递性

依赖的传递性是Maven 2.0中的一项新功能,这样可以避免需要去指定自己的依赖关系需要的库,并自动包含它们。简单来说,就是你从远程库中下载你所依赖的项目,这些项目所依赖的项目你也可以在项目中使用。项目从父项或从属关系中继承的任何项目都可以使用。

以下几种会限制依赖的传递性:

  • 依赖调解: 这决定遇到多个工件版本时使用哪一个依赖的版本。在Maven 2.0只支持使用“最近原则”,最近原则使用依赖关系树中项目最近的版本。例如我们定义A->B->C->D2.0 和 A->E->D1.0,因为A到E到D1.0的路径最短,根据最近原则。则构建A项目时使用D1.0,你可以直接在A项目中添加D2.0的依赖直接强制使用D2.0。注意如果依赖深度树处于相同深度时,直到Maven 2.0.9才使用依赖声明的顺序,谁优先在A项目中声明依赖就使用谁包含的依赖项目。
  • 依赖关系管理: 这允许项目的作者直接指定在项目中遇到的工件版本。在上一节示例中,依赖D直接被添加到A项目中,即使A不直接使用D。A可以直接在依赖管理(<dependencyManagement>标签)中直接添加依赖D强制使用哪一个版本。
  • 依赖的范围: 这允许您只包含适合当前构建阶段的依赖关系。
  • 排除依赖关系: 如果项目X依赖于项目Y,而项目Y依赖于项目Z,则项目X的所有者可以使用“排除”元素将项目Z显式排除为依赖项。
  • 可选依赖关系: 如果项目Y依赖于项目Z,则项目Y的所有者可以使用“可选”元素将项目Z标记为可选依赖项。当项目X依赖于项目Y时,X将仅依赖于Y而不依赖于Y的可选依赖项Z.项目X的所有者可以根据她的选项明确添加对Z的依赖项。(将可选依赖关系视为“默认排除”可能会有所帮助。)

依赖范围

依赖范围可以用于限制依赖的传递性,也影响构建任务的类路径。包含如下6个可用范围:

  • compile:这是默认范围,如果没有指定依赖范围,则使用该范围。compile的依赖关系在项目的所有类路径中可以使用,而且会传播到所依赖的项目。
  • provided: 这个与compile非常相似,但是JDK或容器运行期的依赖。例如可以将Servlet API设置为该选项,因为Web容器提供了这些类,此范围只需在编译和测试类路径中使用,且不具有传递性。
  • runtime: 此范围编译时不使用,运行期使用。它在运行时和测试类路径中,但不在编译类路径中。
  • test: 此范围表示正常使用应用程序中不需要使用的依赖,并且只适用于测试编译和执行阶段。不具有传递性。
  • system: 该范围与provided范围类似,只是必须明确提供包含的JAR。工件始终可以使用,并且不会在存储库中查找。
  • import: 仅在Maven 2.0.9以后版本中使用,此范围仅可在<dependencyManagement>标签中使用。它表示用指定POM的<dependencyManagement>部分中的依赖项替换掉依赖项。由于它们被替换,因此具有import范围的依赖关系实际关系并不参与传递性。

依赖管理

依赖管理是集中依赖信息的机制。当你有一组继承公共父项目的项目时,可以将所有依赖项信息放入到公共POM中,并且可以更简单的引用于子POM中。通过下面的例子可以很好的说明,鉴于这两个POM拓展同一个父POM:

项目A:

 <project>
...
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

项目B:

 <project>
...
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

这两个示例中的POM共享一个共同的依赖关系,并且每个都有一个不重要的依赖关系,这些信息可以像如下示例放在父POM中:

 <project>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version> <exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions> </dependency> <dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency> <dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

然后这两个子POM就变得更简单:

精简后的项目A:

 <project>
...
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency> <dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<!-- This is not a jar dependency, so we must specify type. -->
<type>bar</type>
</dependency>
</dependencies>
</project>

精简后的项目B:

 <project>
...
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<!-- This is not a jar dependency, so we must specify type. -->
<type>war</type>
</dependency> <dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<!-- This is not a jar dependency, so we must specify type. -->
<type>bar</type>
</dependency>
</dependencies>
</project>

注意:在这两个依赖关系引用中,我们必须指定<type/>元素,因为dependencyManagement最小信息集实际上是 {groupId,artifactId,type,classifier}。在大多数情况下,这些依赖关系引用没有classifier,这允许我将标识设置为{groupId,artifactId},因为type默认为jar,classifier默认为null。

导入依赖

导入依赖是在Maven 2.0.9中引入的,所以必须使用该版本或更高版本才能使用导入依赖。因为在项目中只能从单个父继承,在较大项目中可能无法完成某些任务,于是项目可以引入导入托管依赖项,只需要在POM中设置dependency的scope为import即可。如下示例:

项目B:

 <project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>B</artifactId>
<packaging>pom</packaging>
<name>B</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>maven</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>d</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

上面的示例,B项目将会导入A项目的所有依赖,除了d,因为d项目它是在pom中定义的。

项目X:

 <project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>X</artifactId>
<packaging>pom</packaging>
<name>X</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>b</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

项目Y:

 <project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>Y</artifactId>
<packaging>pom</packaging>
<name>Y</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

项目Z:

 <project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>Z</artifactId>
<packaging>pom</packaging>
<name>Z</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>maven</groupId>
<artifactId>X</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>maven</groupId>
<artifactId>Y</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

在上面的示例中,项目Z从X和Y中导入依赖,但是,X和Y都包含了依赖项a,在这里,a版本的1.1将被导入,因为X比Y先声明,而a没有在Z的dependencyManagement中声明。

这个过程是递归的。例如,如果X导入另一个Q,则在处理Z时,它将显示Q中所有的依赖项。

Apache Maven(四):依赖的更多相关文章

  1. Maven(四-2) Maven pom.xml 配置详解

    转载于:http://niuzhenxin.iteye.com/blog/2042102 什么是pom?    pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述 ...

  2. Apache Maven pom文件

    Welcome to Apache Maven Apache Maven is a software project management and comprehension tool. Based ...

  3. 什么是Maven? 使用Apache Maven构建和依赖项管理

    通过优锐课java架构学习中,学到了不少干货,整理分享给大家学习. 开始使用最流行的Java构建和依赖管理工具Maven Apache Maven是Java开发的基石,也是Java使用最广泛的构建管理 ...

  4. apache maven

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAj0AAAGXCAYAAABY/uEUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjw ...

  5. 从初识Maven到使用Maven进行依赖管理和项目构建

    前些天就安装了Maven,以备自己以后整合项目用,尤其是我们的ssh,ssm项目.想必好多人在开始的时候并不清楚Maven是什么,它能够帮助我们干什么. 所以在学习Maven之前我们一定要知道它是什么 ...

  6. ssm框架整合配置,用maven配置依赖jar包

    1.创建maven project 首先在pom.xml中指定工程所依赖的jar包 <project xmlns="http://maven.apache.org/POM/4.0.0& ...

  7. Maven(四-1) Maven的配置文件settings.xml

    转载于:http://www.cnblogs.com/yakov/archive/2011/11/26/maven2_settings.html 概览 当Maven运行过程中的各种配置,例如pom.x ...

  8. 使用Maven进行依赖管理和项目构建

    什么是Maven 1 依赖的管理:仅仅通过jar包的几个属性,就能确定唯一的jar包,在指定的文件pom.xml中,只要写入这些依赖属性,就会自动下载并管理jar包. 2 项目的构建:内置很多的插件与 ...

  9. Maven的依赖和传递性质

    1. 引入项目所需jar包 Maven项目直白的一大特点就是一般情况下不需要去自行下载jar包以及目标jar包的依赖包并导入,只需要在去Maven的中央仓库http://mvnrepository.c ...

  10. maven exclusion 解决maven传递依赖中的版本冲突

    传递依赖是maven最有特色的.最为方便的优点之一,可以省了很多配置.如a 依赖 b,b 依赖c 默认 a也会依赖 c.但是也会带来隐患,如版本冲突.当然maven也考虑到解决办法,可以使用exclu ...

随机推荐

  1. Linux自有服务

    Linux自有服务 Linux自带的功能:运行模式.用户和用户组管理.网络配置.ssh服务 1.运行模式 Linux下的初始化进程:init,进程id为1 该进程的配置文件:/etc/inittab ...

  2. JQUERY实现点击INPUT使光标移动到最后或指定位置

    下面本文章给大家简单介绍一下JQUERY实现点击INPUT使光标移动到最后或指定位置例子,希望对各位有帮助,你要知道面对一个 处女座的 需求者, focus()是远远不够的,比如说“我点进去的时候光标 ...

  3. SAP C4C里如何实现Sales Unit和Seller的自动determination

    先看一个效果,我录了一个视频,发布在视频网站上,大家可以先看看SAP Cloud for Customer里启用了partner 自动determination后的效果. 在SAP Cloud for ...

  4. oracle数据库中创建表空间和临时表空间,以及用户和密码以及设置密码永不过期

    首先进入oracle用户,命令是: su - oracle sqlplus /nolog connect system/123456@ora11g 或者 [oracle@localhost ~]$   ...

  5. BZOJ2976:[POI2002]出圈游戏(exCRT)

    Description 有编号从1到n的n个小朋友在玩一种出圈的游戏,编号为i+1的小朋友站在编号为i小朋友左边.编号为1的小朋友站在编号为n的小朋友左边.首先编号为1的小朋友开始报数,接着站在左边的 ...

  6. 【转】Activity、Window、View的关系

    1.先看一个现象 1 2 3 4 5 6 7 8 9 10 11 public class MainActivity extends Activity {       @Override     pr ...

  7. jackson简单实用

    ---------------------------------------------------------------------------------------------------- ...

  8. c语言实现数组的转置

    #include<stdio.h> int main (){ int i,j,m,n; ][],b[][]; printf("请输入行列式的行数:\n"); scanf ...

  9. 【洛谷P2426】删数

    删数 题目链接 一道裸的区间DP,f[l][r]表示剩下区间[l,r]时的最大价值 可以由f[1~l-1][r]和f[l][r+1~n]转移过来 详见代码: #include<algorithm ...

  10. [luoguP3325][HNOI2012]矿场搭建

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...