Maven依赖的配置

Maven的依赖配置有基本的groupId,artifactId和version等元素组成,其实一个依赖声明可以包含如下的 
一些元素 
     
        ... 
         
             
                ... 
                ... 
                ... 
                ... 
                ... 
                ... 
                 
                     
                    ... 
                   
 
                 
           
 
            ... 
         
   

依赖元素介绍 
    根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或多个 
    项目依赖。每个依赖可以包含的元素有: 
    groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要 
        的,Maven根据坐标才能找到需要的依赖。

    type:依赖的类型,对应于项目坐标定义的packaging.大部分情况下,该元素不必声明,其默认值 
        为jar

    scope:依赖的范围,如test,compile,provided

    optional:标记依赖是否可选

    exclusions:用来排除传递性依赖

    大部分依赖声明只包含基本坐标,然而在一些特殊情况下,其他元素至关重要。

依赖范围 
    Maven在编译项目主代码的时候需要使用一套classpath.

    Maven在编译和执行测试的时候会使用另外一套classpath。

    Maven实际运行项目的时候,又会使用一套classpath。

    依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行classpath)的关系, 
    Maven有以下几种依赖范围: 
    compile:编译依赖范围,如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译,测试,运行三种 
        classpath都有效。典型的例子是spring-core

    test:测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效。典型的例子是JUnit

    provided:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效 
        典型的例子是:servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要 
        Maven重复地引入一遍。

    runtime:运行时依赖范围,使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。 
        典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现 
        上述接口的具体JDBC驱动。

    systemm:系统依赖范围。该依赖范围与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过 
        systemPath元素显式的指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成 
        构建的不可移植,因为应该谨慎使用。systemPath元素可以引用环境变量,如 
         
            javax.sql 
            jdbc-stdext 
            2.0 
            system 
            ${java.home}/lib/rt.jar 
       

    import:(Maven2.0.9及以上):导入依赖范围,该依赖范围不会对三种classpath产生实际的影响,此依赖范围只在dependencyManagement 
        元素下才有效,使用该范围的依赖通常指向一个pom,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的 
        dependencyManagement元素中。

        import范围依赖由于其特殊性,一般都是指向打包类型的pom的模块,如果有多个项目,它们使用 
        的依赖版本都是一致的,则就可以定义一个使用dependencyManagement专门管理依赖的POM,然后 
        在各个项目中导入这些依赖管理配置

         
             
                 
                    com.catt.account 
                    account-parent 
                    1.0-SNAPSHOT 
                    pom 
                    import 
               
 
           
 
       

传递性依赖和依赖范围 
    依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。 
    如account-email对于spring-core的依赖范围是compile,spring-core对于commons-logging的依赖范围是compile,那么account-email对于commons-logging 
    这一传递性依赖的范围也就是compile。 
    假设A依赖于B,B依赖于C,则A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性 
    依赖的范围

    Maven会解析各个直接依赖的POM,将那些必要的间接依赖以传递性依赖的形式引入到当前的项目中。

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

依赖调解 
    Maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入 
    什么传递性依赖。但有时候,当传递性依赖造成问题的时候,就需要清楚地知道该传递性依赖是从哪条依赖路径引入的

    依赖调解(Dependency Mediation)的原则有两个,如下:(为了避免针对同个构件的重复引入) 
    第一原则:路径最近者优先 
    第二原则:第一声明优先。 即在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优先。

可选依赖 
    假设有这样一个依赖关系,项目A依赖于项目B,项目B依赖于项目X和项目Y,B对于项目X和Y的依赖都是可选依赖。根据传递性依赖的定义,如果所有这三个依赖的范围都是 
    compile,那么X\Y就是A的compile范围传递性依赖,然而,由于这里X\Y是可选依赖,依赖将不会得以传递,换句话说,X\Y将不会对A有任何影响。

    在理想的情况下,是不应该使用可选依赖的。 
    使用可选依赖的原因是某一个项目实现了多个特性,如项目是一个持久层隔离工具包,支持多种数据如MYSQL,SYBASE,在构建这个工具包的时候,需要这两种数据库的驱动 
    程序,但在使用这个工具包的时候,只会依赖一种数据库。

排除依赖 
    传递性依赖会给项目隐式地引入很多依赖,这极大的简化了项目依赖的管理,但有时这种特性也会带来问题。

    声明exclusion的时候只需要groupId和artifactId,而不需要version元素,这是因为只需要groupId和artifactId就能唯一确定依赖图中的某个依赖。

    排除依赖: 
    排除不稳定的传递性依赖构件,另外再显式在当前项目中声明该类库的某个正式发布的版本。 
    想替换某个传递性依赖,比如Sun JTP API,Hibernate依赖于这个JAR,但是由于版本的因素,该类库不在中央仓库中,而Apache Geronimo项目有一个对应的实现 
        这时就可以排除Sun JAT API,再声明Geronimo的JTA API的实现

归类依赖 
    如果一个项目依赖同一项目的多个不同模块,如一个项目依赖springframework的多个模块,因为这些依赖的版本都是相同的,且可以预见,如果将来需要升级,则这些 
    依赖的版本会一直升级。

    这样可以定义maven的属性,然后通过${}的方式引用

优化依赖: 
    Maven会自动解析所有项目的直接依赖和传递性依赖,并且根据规则正确判断每个依赖的范围,对于一些依赖, 
    也能进行调节,以确保任何一个依赖只有唯一的版本在依赖中存在,在这些工作之后,最后得到的那些依赖被称为 
    已解析依赖(Resolved Dependency). 可以运行如下命令查看当前项目的已解析依赖 
    mvn dependency:list 
    mvn dependency:tree 
    mvn dependency:analyze

坐标和依赖是任何一个构件在Maven世界中的逻辑表达方式;而构件的物理表示方式是文件,Maven通过仓库来统一管理这些文件

你可能感兴趣的:(Maven依赖的配置)