Maven(二):Maven概念模型及坐标与依赖

本文介绍了Maven的概念模型,重点解析了坐标的组成(groupId、artifactId、version等)及其作用,以及依赖管理,包括依赖的类型、范围(如compile、test等)、传递性依赖和依赖冲突的解决原则。同时,提到了optional和exclusion元素在管理项目依赖中的作用。
摘要由CSDN通过智能技术生成

Maven概念模型

Maven作为项目管理工具软件,可以通过一小段描述信息来管理项目的构建,安装并生成报告和文档。其中主要核心可以分为三步:
(1)根据项目pom.xml文件所描述的信息转换为POM (项目对象模型 Project Object Model),并通过坐标与依赖关系找出该项目所依赖的包,这块也是本章介绍的内容
(2)去本地或远远程仓库中找到项目依赖的包引入项目中(这一块将在后面的仓库与配置中讲解)
(3)根据mvn命令所对应生命周期来执行相应的插件,获得对应的输出 (这一块将在后面的生命周期和插件中讲解)在这里插入图片描述
下面从坐标和依赖两块来看pom.xml中常见标签

坐标

为了能自动化地解析任何一个Java构件, Maven必须将它们唯一标识, 这就是依赖管理的底层基础-坐标.
任何一个构件都必须明确定义自己的坐标, 坐标元素包括groupId、artifactId、version、packaging、classfier

<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
  • groupId:定义当前模块隶属的实际Maven项目
  • artifactId:定义实际项目中的一个Maven模块
  • version:定义当前项目所处版本
  • packaging:定义Maven项目打包方式, 有war、pom、maven-plugin等,默认jar
  • classifier:用来帮助定义构建输出的一些附属构件。附属构建与主构件对应,如主构件是nexus-indexer-2.0.0.jar,该项目还会通过插件生成如nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar这样一些附属构建,代表了java文档和源代码 javadoc、sources就是两个附属构建的classifier。

上述5个元素中groupId、artifactId、version是必须定义的,packaging是可选的,classifier是不能直接定义的,必须有插件的帮助才能生成。
项目的文件名是与坐标相对应的,一般为:artifactId-version[-classfier]. packaging,本地仓库中项目所在位置也与坐标相对应,一般为:本地仓库地址/groupId/ artifactId/ version/ artifactId-version[-classfier]. Packaging

依赖

Maven的依赖管理,使我们不必再到开源项目的官网一个个下载开源组件, 然后再一个个放入classpath. 一个依赖声明可以包含如下元素:

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

dependencies可以包含一个或多个dependency元素,以声明一个或多个项目依赖,下面来看下这些元素:

groupId、artifactId、version

依赖的基本坐标,Maven根据坐标才能找到需要的依赖。

type

依赖的类型, 对应于项目坐标定义的packaging,默认jar

scope

依赖范围

一.依赖范围

依赖范围就是用来控制依赖与三种classpath(编译classpath、测试classpath、运行classpath)的关系,Maven有以下几种依赖范围:

  • compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效。
  • test: 测试依赖范围。只对于测试classpath有效,只对测试代码有效。
  • provided:
    已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api,打包的时候这个包不会打进去。
  • runtime:运行时依赖范围。对于测试,运行classpath有效。例如jdbc驱动。

Compile、runtime打包会打进去,test、provided打包不会打进去
此外还有两种:

  • system:系统依赖范围。依赖范围与pprovided一致,由于此类依赖往往与本机系统绑定,可能造成构建的不可移植,应谨慎使用。
  • import:导入依赖范围,不会对三种classpath产生影响。
二.传递性依赖

依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。假设A依赖于B,B依赖于C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖,那么第一直接依赖范围和第二指节依赖反为决定了传递性依赖范围。如下表素食,最左边一列是的第一直接依赖范围,最上面一行是第二指节额依赖范围,中间交叉的单元格则表示传递性依赖范围

compiletestprovidedruntime
compilecompile--runtime
testtest--test
providedprovided-providedprovided
runtimeruntime--runtime
三.依赖冲突

如果项目A有这样的依赖关系:A->B->C->X(1.0),A->D->X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版本的X,那么哪个X会被Maven解析使用呢?
第一原则:路径最近者优先
对于上面的例子中X(1.0)路径长度为3,X(2.0)的路径长度为2,因此X(2.0)会被解析使用。
那如果碰到A->B->Y(1.0),A->C->Y(2.0),Y(1.0)和Y(2.0)依赖路径长度一样时又该解析哪个呢?
第二原则:第一声明者优先
在依赖路径长度相等的前提下,在POM中依顺序决定谁会被解析使用

optional

标记依赖是否可选。可能项目中实现了两个特性,并且这两种特性是互斥的,用户不能同时使用这两种特性。比如一个Jar包支持MySQL与Oracle两种DB, 因此其构建时必须添加两类驱动, 但用户使用时只会选择一种DB。 元素表示依赖为可选依赖,只会对当前项目产生影响,当其他项目依赖于当前项目时,optional标记的依赖不会被传递。
在这里插入图片描述

exclusion

用来排除传递性依。exclusions可以包含一个或多个exclusion子元素,因此可以排除一个或多个传递性依赖。

参考:《Maven实战》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值