Maven3坐标与依赖

坐标

Maven的坐标用来惟一标示一个项目在Maven仓库的位置,Maven的坐标主要由groupId、artifactId、version、packaging、classifier 5个元素组成,其中groupId、artifactId、version是必要的元素,而packaging、classifier能够省略。java

  • groupId:定义当前项目所属的项目包,对应了Maven仓库中的目录结构spring

  • artifactId:通常为当前项目名称,对应了项目名称目录名sql

  • version:项目的版本,对应了版本目录名数据库

  • packaging:指定打包的方式,默认为jar包,可选(war、maven-plugin、pom、zip等)api

  • classifier:用于帮助定义构建输出的一些附属构建,不能直接定义一般有插件帮助生成maven

当使用坐标去maven仓库中找寻依赖文件时,将会使用如下路径查找:ide

$RESPORITY_HOME/groupId(replace . to /)/artifactId/version/artifactId-version[-classifier].packaging (当packaging为maven-plugin时扩展名也为jar)工具

当version为SNAPSHOT(快照)版本,发布到远程仓库,SNAPSHOT会被替换成当时的时间戳,当在被依赖时,会时间最近时间戳的版本测试


依赖

Maven的pom文件中配置依赖大体包含下面的元素:spa

<dependency>
  <groupId></groupId>
  <artifactId></artifactId>
  <version></version>
  <type></type>
  <scope></scope>
  <optional></optional>
  <exclusions>
    <exclusion></exclusion>
  </exclusions>
</dependency>
  • groupId、artifactId、version用来惟一的表示一个构建

  • type:依赖的类型,对应了项目坐标定义时的packaging,默认为jar

  • scope:依赖的范围,可选值有compile、test、provided、runtime、system、import

  • optional:标记依赖是否为可选依赖,默认为false

  • exclusions:用来排除传递性依赖

依赖的范围

  • compile:编译范围依赖,默认选项,对于编译、测试、运行三个阶段都须要依赖

  • test:测试范围依赖,只在测试阶段须要用的依赖,如junit

  • provided:已提供范围依赖,对于编译和测试阶段须要此依赖,当运行期不须要,常见的如servlet-api,运行期容器提供

  • runtime:运行时范围依赖,对于运行和测试阶段须要此依赖,如JDBC驱动的实现,代码在编译时只须要JDK提供的JDBC接口

  • system:系统范围依赖,与provided依赖方位同样,只是使用system必须显示的使用systemPath指定依赖文件路径

  • import:这个依赖范围比较特殊,并不会影响编译、测试、运行三个阶段,是用来复用某个pom文件中配置的dependencyManagement下的配置内容的,因此使用这个scope的dependency必须是知足一些条件才有效:

            (1)必须在dependencyManagement元素内

            (2)packging必须为pom


依赖的传递

       当前项目的直接依赖可能也须要依赖其余的jar,这种依赖叫作二级依赖,Maven会使用依赖的传递机制帮咱们处理好二级及以上的依赖,好比以下依赖:

        project -> spring-core -> commons-logging

        当前项目依赖于spring-core,而spring-core又依赖于commons-logging,咱们并不须要在project的pom文件中显示的申明commons-logging的依赖,Maven会经过spring-core的pom文件最终将commons-logging的依赖加载到project项目中,可是在依赖的传递过程当中也会有必定的范围规则,以下图:

一级依赖\二级依赖

compile

test

provided

runtime

compile

compile ——

——

runtime

test

test

——

——

test

provided

provided

——

provided

provided

runtime

runtime

——

——

runtime

简而言之就是

  • 当二级依赖的范围是compile时,传递依赖后的方位和一级依赖相同;

  • 当二级依赖的范围是test时,此依赖不会传递;

  • 当二级依赖的范围是provided时,只有一级依赖也为provided才会传递;

  • 当二级依赖的范围是runtime时,除了一级依赖为compile,会传递runtime范围,其他的范围与一级依赖一致

依赖的调解


    当项目的间接依赖存在相同的项目不一样的版本时,Maven不容许相同的项目被加载屡次,这时候就须要对依赖进行调解,好比:

    A->B->C(1.0) ,A->D->C(2.0),A->E->F->C(3.0)

    A依赖于B和D和E,但B依赖于C的1.0版本,而D依赖于C的2.0版本,F依赖于C的3.0版本,不可能A中加载三个版本的C,这样作是显然是不对的,因此Maven在遇到这种状况是制定了一个规则来肯定到底加载哪一个版本的C,规则以下:

  1. 首先以依赖的深度来选择,浅的优先,因此C(3.0)不可能被加载

  2. 在深度相同的状况下,pom文件中先被解析到的优先

可选依赖

    上面有提到pom文件中声明依赖时可使用<optional>true</optional>声明该依赖为可选依赖,可选依赖不会被传递,如:

    A->B,B->C(可选),B->D(可选)

    想上面的C和D都不会被传递,须要在A的pom中明确的声明是使用C仍是D,举个形象的例子,B是一个持久化隔离的工具包,它支持多种数据库,C、D能够看做Mysql的链接包、Oracle的链接包,C、D在B的pom中的依赖声明就是可选的,他们不会被传递给A,在A中须要根据实际使用的数据库,声明使用的链接包

相关文章
相关标签/搜索