`

maven依赖管理

阅读更多
1.依赖范围说明
由于不同的包在不同的地方用到,像junit我们只有在做测试的时候会用到这个包,在我们项目发布的时候,用不到这个包;还有servlet-api,在项目编译的时候将会用到这个包,而项目发布的时候就不会用到这个包,因为一般容器已经自带这个包,如果我们导入,有可能会出现冲突,所以maven引入了依赖范围这个概念,即我们上面提到的scope来解决这个问题。Maven中有主要有以下这几种依赖范围:
1)  test:指的是测试范围有效,在编译打包、运行时都不会使用这个依赖。例如:junit jar包。

2)  compile:指的是编译范围有效,在编译、测试、打包、运行时都会将依赖存储进去。如果没有指定,就会默认使用该依赖范围。例如:hibernate jar包。

3)  provided:在编译和测试的过程有效,最后生成包时不会加入,运行时自然也没效果。例如:servlet-api,因为servlet-api,tomcat等web服务器已经存在该jar包了,如果再打包可能会有冲突。

4)  runtime:在测试、运行的时候依赖,在编译的时候不依赖。例如:JDBC驱动,项目代码只需要jdk提供的jdbc接口,只有在执行测试和运行项目的时候才需要实现jdbc的功能。

5)  system:系统依赖范围。该依赖范围与provided所表示的依赖范围一致,对于编译和测试有效,但在运行时无效。只是使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用,systemPath元素可以引用环境变量。

6)  import(Maven 2.0.9及以上):导入依赖范围。该依赖范围不会对三种classpath产生实际的影响。

上述除import以外的各种依赖范围与三种classpath的关系如下:
依赖范围(scope)测试classpath编译classpath运行classpath例子
compileYYYspring-core
provided Y servlet-api
testY junit
runtimeY YJDBC驱动实现
systemYY 本地的,Maven仓库之外的类库文件

2.传递性依赖和依赖范围
Maven的依赖是具有传递性的,比如A->B,B->C,那么A间接的依赖于C,这就是依赖的传递性,其中A对于B是第一直接依赖,B对于C是第二直接依赖,C为A的传递性依赖。

在平时的开发中,如果我们的项目依赖了spring-core,依赖范围是compile,spring-core又依赖了commons-logging,依赖范围也是compile,那么我们的项目对于commons-logging这一传递性依赖的范围也就是compile。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。我们通过下面这个表格来说明,其中最左边一栏是第一直接依赖,最上面那一栏为第二直接依赖。中间交叉的是传递性依赖范围。
CompileTestProvidedRuntime
CompileCompile Runtime
TestTest Test
ProvidedProvided ProvidedProvided
RuntimeRuntime Runtime

例如:第一直接依赖范围是Test,第二直接依赖范围是Compile,那么传递性依赖的范围就是Test,大家可以根据这个表去判断。

仔细观察一下表格,我们可以发现这样的规律:

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

3.依赖调解
假设项目A有两个传递性依赖C,但是路径不同:A->B->C-X(1.0),A->D->X(2.0)。为了避免造成依赖重复,需要选择一个依赖路径。
Maven里面对于传递性依赖有以下几个规则:

1) 最短路径原则:如果A对于依赖路径中有两个相同的jar包,那么选择路径短的那个包,路径最近者优先,上述会选X(2.0)。

2) 第一声明优先原则:如果A对于依赖路径中有两个相同的jar包,路径长度也相同,那么依赖写在前面的优先。例如:A->B->F(1.0),A->C->F(2.0),会选F(1.0)。

3) 可选依赖不会被传递,如A->B,B->C,B->D,A对B直接依赖,B对C和D是可选依赖,那么在A中不会引入C和D。可选依赖通过optional元素配置,true表示可选。如果要在A项目中使用C或者D则需要显式地声明C或者D依赖。
4.排除依赖
传递性依赖会给项目隐式的引入很多依赖,这极大的简化了项目依赖的管理,但是有些时候这种特性也会带来问题,它可能会把我们不需要的jar包也引入到了工程当中,使项目结构变得更复杂。或者你想替换掉默认的依赖换成自己想要的jar包,这时候就需要用到依赖排除。
  <dependency>    
       <groupId>org.springframework</groupId>  
       <artifactId>spring-core</artifactId>  
       <version>3.2.8</version>  
       <exclusions>  
             <exclusion>      
                  <groupId>commons-logging</groupId>          
                  <artifactId>commons-logging</artifactId>  
             </exclusion>  
      </exclusions>  
 </dependency> 

例子中spring-core包依赖了commons-logging包,我们使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。需要注意的是,声明exclusions的时候只需要groupId和artifactId,而不需要version元素,这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。换句话说,Maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的两个依赖。
5.把依赖归为一类
在项目开发中往往会引入同一个项目中的多个jar包,比如最常见的spring,如果我们项目中用到很多关于Spring Framework的依赖,它们分别是spring-core-3.2.8.RELEASE, spring-beans-3.2.8.RELEASE,spring-context-3.2.8.RELEASE,它们都是来自同一项目的不同模块。因此,所有这些依赖的版本都是相同的,而且可以预见,如果将来需要升级Spring Framework,这些依赖的版本会一起升级。因此,我们应该在一个唯一的地方定义版本,并且在dependency声明引用这一版本,这一在Spring Framework升级的时候只需要修改一处即可。

首先使用properties元素定义Maven属性,实例中定义了一个<springframework.version>子元素,其值为3.2.8.RELEASE,有了这个属性定义之后,Maven运行的时候会将pom.xml中所有的${springframework.version}替换成实际的值:3.2.8.RELEASE。也就是可以使用$和{}的方式引用Maven的属性。然后将所有springframework依赖的版本替换成<version>${springframework.version}</version>这个样子,就和在Java代码中定义了一个不变的常量一样,以后要升级版本就只需要把这个值改了。
<properties>
  <junit.version>4.11</junit.version>
  <oracle.version>10.2.0.4</oracle.version>
  <springframework.version>3.2.8.RELEASE</springframework.version>
  <mybatis.version>3.2.2</mybatis.version>
  <mybatis-spring.version>1.2.0</mybatis-spring.version>
  <mysql-driver.version>5.1.25</mysql-driver.version>
</properties>
<dependencyManagement>
  <dependencies>
    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>${junit.version}</version>
       <scope>test</scope>
    </dependency>

    <dependency>
       <groupId>org.mybatis</groupId>
       <artifactId>mybatis</artifactId>
       <version>${mybatis.version}</version>
    </dependency>

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

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis-spring.version}</version>
    </dependency>
 
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql-driver.version}</version>
    </dependency>
    
    <dependency>
       <groupId>com.oracle</groupId>
       <artifactId>ojdbc14</artifactId>
       <version>${oracle.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>

参考:https://www.cnblogs.com/AlanLee/p/6187843.html
分享到:
评论

相关推荐

    Maven依赖管理项目构建工具.pdf

    Maven依赖管理项目构建工具

    maven依赖管理 继承管理

    Maven就可以替我们自动的将当前jar包所依赖的其他所有jar包全部导入进来,无需人工参与,节约了我们大量的时间和精力。用实际例子来说明就是:通过Maven导入commons-fileupload-1.3.jar后,commons-io-2.0.1.jar会被...

    Maven依赖管理项目构建工具(保姆级教学)

    Maven依赖管理项目构建工具(保姆级教学)

    chm版本Maven教程

    Maven依赖管理 Maven自动化部署 Maven Web应用 Eclispe IDE集成Maven NetBeans IDE集成Maven Eclipse构建Maven项目 转换基于Maven的Java项目支持Eclipse IDE 转换基于Maven的Web应用程序支持Eclipse IDE 使用Maven...

    activiti开发项目maven依赖POM文件

    基于ACTIVITI引擎进行开发,利用maven进行依赖管理,本文件列出来具体的依赖项

    maven依赖的压缩包

    Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。

    Maven权威指南 很精典的学习教程,比ANT更好用

    Maven依赖管理 (Dependency Management) 3.5.6. 站点生成和报告 (Site Generation and Reporting) 3.6. 小结 4. 定制一个Maven项目 4.1. 介绍 4.1.1. 下载本章样例 4.2. 定义Simple Weather项目 4.2.1...

    前后端项目启动教程课程,配套后端Maven依赖包

    前后端项目启动教程课程,配套后端Maven依赖包,适用于SpringBoot3.1版本,用于 https://blog.csdn.net/qq_41464123?type=download 系列项目...在Maven中,我们可以使用依赖管理器来管理项目所需的外部JAR包或库文件。

    maven常用依赖.txt

    Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。 书中讲解了网络基础知识、TCP/IP基础知识、数据链路、IP协议、IP协议相关技术、TCP与UDP、路由协议、应用协议、网络安全等内容,引导读者了解和...

    基于SSM的人事管理系统源码+项目说明(使用Maven进行依赖包控制).zip

    基于SSM的人事管理系统源码+项目说明(使用Maven进行依赖包控制).zip 基于SSM的人事管理系统源码+项目说明(使用Maven进行依赖包控制).zip 基于SSM的人事管理系统源码+项目说明(使用Maven进行依赖包控制).zip ...

    Apache-Maven-Cookbook.pdf

    Maven入门开发指南,全面介绍Maven依赖管理工具的使用

    JSONObject相关jar包和maven管理jar包

    JSONObject对象相关的jar包依赖,一共有6个;还有maven环境下管理的jar包

    Maven权威指南中文版(完整)

    3.5.5. Maven依赖管理 (Dependency Management) .............. 36 3.5.6. 站点生成和报告 (Site Generation and Reporting) ...... 38 3.6. 小结 ..................................................... 38 4. ...

    idea插件一键解决maven依赖冲突

    本插件参考58开源插件MavenManager,采用dependencyManagement方式,一键解决Java开发过程中使用maven作为依赖管理时的jar包依赖冲突问题,相比MavenHelper更加省时省力,jar包版本采用最新版本号原则

    用于存放java源码和Thinking of Java的资源.rar

    这些工具伴随着Java一起出现,在各自辉煌之后还在一直使用。 Apache Ant:基于XML的构建...Gradle:使用Groovy(非XML)进行增量构建,可以很好地与Maven依赖管理配合工作。 字节码操作 编程方式操作字节码的开发库。

    Maven使用详解.doc

    Maven 是一个项目管理和构建自动化工具,Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。

    spring框架api中文版.zip(spring开发手册)

    依赖关系管理和命名约定 Spring依赖和依靠弹簧 Maven依赖管理 艾薇依赖管理 1.3.2。 日志 不使用通用日志 使用SLF4J 使用Log4j 二世。 什么是新的在春季3 2。 新特性和增强功能在Spring框架3.0 2.1。 Java 5 2.2。 ...

    apache-maven3.5 依赖包

    eclipse和Myeclipse项目开发中,maven项目管理依赖配置包

Global site tag (gtag.js) - Google Analytics