二、坐标与依赖

坐标

前面一章已经讲过了,在maven的世界里,所有的一切都是以坐标定位的,是时候对坐标做一个详细解释了

TIM图片20170721230132.gif

在坐标中,有以下几个成员groupId,artifactId,version,packaging,classifier
groupId表示方式通常与包名表示方式类似,通常与域名反向一一对应,格式为域名或组织名反向.项目名。比如:groupId=org.sonatype.nexus, sonatype.org为一个组织,nexus为该组织下的一个实际项目
artifactId该元素定义实际项目中的某一个模块,推荐以实际项目名称做前缀
version定义maven项目当前所处版本,有snapshot,alpha,beta,release几种类型的版本类型,具体在后面章节专门介绍
packaging定义当前maven项目的打包方式,有jar,pom,war几种方式,打包方式通常与项目生成构建的文件扩展名对应,比如下面的依赖groupId:artifactId:version:packaging=org.sonatype.nexus:nexus-indexer:2.0.0:jar将会生成:nexus-indexer-2.0.0.jar
classifier用于定义构建输出一些附属构建,比如javadoc,source,但是不能直接定义classifier,因为附属构建不是项目直接生成的,需要借助插件

项目文件名
maven中项目文件名的生成完全依赖于坐标,生成的一般规则为:artifactId-version[-classifier].packaging

依赖

依赖是maven中一大核心,项目中用到的所有第三方资源都是通过依赖导入到项目中使用的,下面是依赖的基本架构:

<dependencies>
    <dependency>
        <groupId></groupId>
        <artifactId></artifactId>
        <version></version>
        <type></type>
        <scope></scope>
        <optional></optional>
        <exclusions>
            <exclusion>
                <groupId></groupId>
                <artifactId></artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
  • groupId,artifactId,versionmaven坐标系的基本坐标,对于每一个构建来说都是必须的
  • type声明依赖的类型,与项目packaging对应,默认值为jar
  • scope依赖范围,maven中对编译,测试,运行三个环境提供了6种依赖范围test,provide,import,compile,runtime,system,他们之间的具体关系将在下面讲到
  • optional标记依赖是否为可选依赖,默认为false
  • exclusions用来排除一些传递性依赖

依赖范围scope
maven中有3中classpath编译测试运行
围绕这三种classpath又分出了6种不同的依赖范围
compile(default),test,provide,runtime,system,import

图片1.png

compile默认依赖范围,对于编译、测试、运行有效,比如我们需要用到的spring-core
test测试范围,只对测试环境有效,正式部署时将不会被打包,也就是只能在代码测试中起作用,比如junit
provided已提供范围,针对编译、测试有效,运行时无效,比如servlet-api,tomcat服务器内部已经提供了
runtime测试、运行时有效,对编译无效,比如jdbc驱动,项目主代码的编译只需要jdk提供的jdbc接口,只有在测试和运行时才需要上述接口的具体实现
system系统依赖范围,该依赖与三种classpath的关系和provided依赖范围完全一致,但是使用system范围的依赖时必须通过systemPath元素显示的指定依赖文件的路径,使用此类依赖主要目的是为了使用系统本机jar,会与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用
下面是一个system依赖范围的使用方式

    <groupId>javax.sql</groupId>
    <artifactId>jdbc-stdext</artifactId>
    <version>2.0</version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/dt.jar</systemPath>
</dependency>

import导入依赖范围,该依赖范围不会对上面提到的三种classpath产生实际的影响,只针对dependencyManagement有效

传递性依赖
在引入一个依赖的时候,被引入的依赖同时又依赖了其他开源类库,这时该项目就发生了传递性依赖
maven传递性依赖为用户减少了配置依赖不必要的麻烦,我们在实际引入一个依赖时无需考虑该依赖是否还需要额外的引入其他开源类库,maven传递性依赖自动为我们处理了这类问题

传递性依赖和依赖范围
依赖范围(scope)不仅可以控制与三种classpath的关系,而且还会影响传递性依赖

图片2.png
图片4.png

从上面的图片中可以得出一些结论:

  • 第二依赖如果是compile,那么最后得到的jar包依赖范围为第一依赖的值
  • 第二依赖如果是test,则jar包将不被包含(依赖范围为空)
  • 第二依赖如果是provide, 只有第一依赖为providejar包有效,且依赖范围为provide
  • 第二依赖如果是runtime, 当第一依赖为compile时,最终依赖为runtime,其他范围不变

依赖调节
既然maven中存在传递依赖,那么又会存在一系列问题,比如

图片5.png

针对上面情况产生规则:
1 最短路径优先原则
maven最终会使用A->D->C
如果原则一不能解决问题,比如两个方向的路径相同,这时会怎么办?
图片6.png

2 第一声明优先
也就是说在pom.xml中谁先声明则选谁,与版本没有关系,如果B先于D声明,则最后会取 A->B->Y

可选依赖
可选依赖的声明格式形如:

<dependency>
    ...
    <optional>true</optional>
    ...
</dependency>

可选依赖的一个使用场景是当对某一业务有不同实现,比如对数据库的操作,有jdbc,oracle等实现类库,但理想情况下是不应该使用可选依赖的,对于项目实现的多样性,可以抽离成不同的项目,让用户自己选择具体依赖实现,比如对jdbc实现分离出一个项目模块,对oracle实现又分离出另一个模块供用户选择性使用

依赖排除(exclusions)
在某些情况下,我们需要排除传递依赖的其他开源类库,而引入指定的类库,这时需要使用exclusions来对依赖进行排除

<dependency>
    <exclusions>
        <exclusion>
            <groupId></groupId>
            <artifactId></artifactId>
        </exclusion>
    </exclusions>
</dependency>

在对依赖进行排除时只需要指定groupId,artifactId即可,因为在一个pom文件中,优化的依赖不可能存在相同的groupId,artifactId不同的version的依赖存在

归类依赖(properties)
对于来自同一个项目的不同模块,他们的版本都是一致的,考虑到代码到简洁便于修改以及重复问题,可以将version放在一处统一管理,这里就需要用到properties元素

<properties>
    <spring.version>4.2.3</spring.version>
</properties>

在使用了属性变量后,在pom的依赖管理中使用到指定的变量就可以采用${property}的方式引用了,比如

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>

依赖优化
我们可以借助maven提供的一些命令工具来了解当前依赖的具体情况

列表显示依赖情况list
mvn dependency:list
命令将会列出当前项目中使用的依赖包信息,包括版本、依赖范围等信息

图片7.png

树形结构显示依赖情况tree
mvn dependency:tree
将会以树形形式展现当前项目传递依赖的情况

图片8.png

分析依赖analyze
mvn dependency:analyze
使用上述命令可以了解当前项目在编译时有哪些使用到了但没有明确指定的依赖(used undeclared dependencies)以及明确指定但是没有被使用的依赖(unused declared dependencies)

图片9.png

used undeclared dependencies:
对于这类依赖意味着项目存在风险,因为项目直接使用了传递依赖,当依赖的包版本升级可能会导致传递依赖失效,这时项目极有可能会编译报错,针对这类型问题的解决方式是:在项目中显示指定所有使用到的依赖
unused declared dependencies:
针对这类依赖则需要小心分析,因为mvn dependency:analyze只会分析编译主代码和测试代码需要使用到的jar,对于执行测试和运行时的依赖是无法察觉的,删除需小心谨慎!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • maven项目中需要使用到其它依赖时,则需要在pom.xml中配置<dependency>元素也就是依赖声明,这样...
    zlcook阅读 1,800评论 1 3
  • 何为Maven坐标 是Maven定义的一组规则,世界上任何一个构建都可以使用Maven坐标唯一标识,Maven坐标...
    依然爱笑的薰衣草阅读 441评论 0 0
  • 一 、说明 我们知道maven能帮我们管理jar包,那么它是怎么管理的呢? 二 、什么是坐标? 1、数学中的坐标 ...
    唯老阅读 1,119评论 0 1
  • 一、maven的两个作用 项目自动化构建,通过命令行就可以完成整个项目构建过程,不需要我们手动地进行项目构建 管理...
    lifeline张阅读 834评论 0 1
  • 一、什么是Maven坐标Maven定义了一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识,坐标元素包括...
    JarvisTH阅读 195评论 0 0