您的位置:首页 > 其它

maven坐标和依赖详解

2017-04-06 23:38 281 查看

1、坐标

maven坐标为各种构建引入了秩序,任何一个构建都必须明确定义自己的坐标,而一组maven坐标是通过一些元素定义的,他们是groupId,artifactId,version,packaging,classifier。


例如:

<groupId>org.nexus</group>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>


groupId:定义当前maven项目所属的实际项目。maven项目和实际项目不一定是一一对应的关系,比如springFrameword对应的maven项目有spring-core,spring-context等。

artifactId:定义实际项目中的一个maven项目(模块),使用实际项目名称做为artifactId的前缀,方便寻找实际构建。

version:定义maven项目当前所处的版本。

packaging:定义maven项目的打包方式。打包方式通过与所生成构建的文件扩展名对应,如上最后生成的文件名为nexus-indexer-2.0.0.jar。当不定义packaging时默认使用jar方式打包。

classifier:帮助定义构建输出的一些附属构建。附属构建与主构建对应,比如上面主构建是nexus-indexer-2.0.0.jar,可能还会通过其他一些插件生成nexus-indexer-2.0.0-javadoc.jar等。

上面五个元素中groupId,artifactId,version是必须定义的,packaging是可选的,classifier是不能直接定义的。

2、依赖的配置

一个依赖还可以包含如下的一些元素:

<project>
<dependencies>
<dependency>
<groupId>...</groupId>
<version>...</version>
<artifactId>...</artifactId>
<classifier>...</classifier>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>
...
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>


type:依赖的类型,对应项目坐标定义的packaging。大部分情况下不需要审明;

scope:依赖的范围,后续讲解;

optional:标记依赖是否可选,后续讲解;

exclusions:排除传递性依赖,后续讲解;

3、依赖范围(scope)

compile:编译依赖范围。没有指定scope,默认使用该范围。使用此范围,对于编译、测试、运行三种classpath都有效;

test:测试依赖范围;

provided:已提供依赖范围,对于编译和测试都有效,但在运行时无效,典型的例子是servlet-pai;

runtime:运行时依赖范围,对于测试和运行有效;

system:系统依赖范围。和provided的依赖范围一致;

import:导入依赖范围,不对classpath产生影响。

4、传递性依赖

概念

假设有一个项目A,有一个compile范围的spring-core依赖,spring-core有一个compile范围的commons-logging依赖,那么commons-loggin就会成为项目A的compile范围依赖,那么我们就叫commons-logging是项目A的一个传递性依赖。

传递性依赖和范围依赖

传递依赖的规律:假设A依赖于B,B依赖于C,那么A对于B就是第一直接依赖,B对于C就是第二直接依赖,A对于C就是传递性依赖,第一直接依赖和第二直接依赖的范围决定了传递性依赖的范围。

当第二直接依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致;当第二直接依赖的范围是test的时候,依赖不会传递;当第二直接依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为provided;当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递性依赖的范围为runtime。

依赖调解

假设项目A有这样的依赖关系:A -> B -> C -> X(1.0)/A -> D -> X(2.0),X是A的传递性依赖。到底是选择1.0还是2.0,maven根据路径最优者优先原则处理,所以X(2.0)会被使用。

当依赖的路径一致的时候,选择先定义的依赖。

可选依赖

当设置optional=true的时候是可选依赖。假设项目A实现了两个特性,其中一个依赖X,另外一个依赖Y,而且两个特性是互斥的,不能同时使用这两个特性。例如:A是一个持久层的工具包,支持多中数据库,在使用这个工具包的时候,需要这两种数据库的驱动程序,但是在使用这个工具包的时候只会依赖一种数据库。

<dependency>
<groupId>mysql</groupId>
....
<optional>true</optional>
</dependency>
<dependency>
<groupId>oracle</groupId>
....
<optional>true</optional>
</dependency>


上面示例中对于mysql和oracle的驱动引用都是可选依赖,他们只会对当前项目产生影响,当其他项目依赖于此项目时是不会传递的。所以其他项目需要显示的申明mysql或者oracle的驱动。

5、排除依赖

假设项目A依赖于项目B,但是不想引入传递性依赖C,而是想自己显示地申明对于项目C1.2版本的依赖。代码中使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。声明exclusion的时候只需要groupId和artifactId,而不需要声明version元素,因为依赖都是全部排除,有这两个元素就能确定是哪一个依赖。

6、归类依赖

很多时候同一个类型的依赖版本都是一致的,比如spring的spring-core,spring-context等都会使用相同的版本,为了方便修改版本信息一般会声明一个版本属性:

<properties>
<springframework.version>3.0.1</springframework.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  maven