maven坐标和依赖详解

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、传递性依赖

  1. 概念
    假设有一个项目A,有一个compile范围的spring-core依赖,spring-core有一个compile范围的commons-logging依赖,那么commons-loggin就会成为项目A的compile范围依赖,那么我们就叫commons-logging是项目A的一个传递性依赖。
  2. 传递性依赖和范围依赖
    传递依赖的规律:假设A依赖于B,B依赖于C,那么A对于B就是第一直接依赖,B对于C就是第二直接依赖,A对于C就是传递性依赖,第一直接依赖和第二直接依赖的范围决定了传递性依赖的范围。
    当第二直接依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致;当第二直接依赖的范围是test的时候,依赖不会传递;当第二直接依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为provided;当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递性依赖的范围为runtime。
  3. 依赖调解
    假设项目A有这样的依赖关系:A -> B -> C -> X(1.0)/A -> D -> X(2.0),X是A的传递性依赖。到底是选择1.0还是2.0,maven根据路径最优者优先原则处理,所以X(2.0)会被使用。
    当依赖的路径一致的时候,选择先定义的依赖。
  4. 可选依赖
    当设置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>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值