`

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

    五、基于IDEA 进行Maven依赖管理 1. 依赖管理概念 Maven通过pom.xml文件管理项目的依赖,每个依赖都有其GAV信息,Maven会自动解决依赖的版本和传递性依赖。 2. Maven工程核心信息配置和解读(GAVP) pom.xml文件中...

    maven依赖小例子

    Maven依赖管理是Maven的核心功能之一,它允许开发者声明项目所依赖的库,并自动下载这些库到本地仓库,以便于构建和运行项目。在Maven的项目对象模型(Project Object Model,POM)中,依赖被定义在`&lt;dependencies&gt;`...

    maven依赖管理 继承管理

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

    Maven的依赖验证项目

    【Maven的依赖验证项目】是一个关于Maven项目管理和依赖管理的实践案例,它与CSDN博主songdeitao的一篇文章《Maven依赖管理详解》相关联。在这个项目中,我们将深入理解Maven如何处理项目的依赖关系,以及如何有效地...

    Maven 依赖详细理解.pdf

    依赖范围(scope)是Maven依赖管理的一个重要概念。scope定义了依赖项的使用范围,主要有以下几个选项:compile、provided、runtime和test。compile表示依赖项在编译时需要,provided表示依赖项在编译和测试时需要,但...

    深入Maven依赖管理:精通依赖范围的艺术

    Maven的核心功能之一是依赖管理,它允许用户通过在`pom.xml`文件中声明依赖关系,自动处理项目所需的第三方库。 Maven工程的构建过程中,真正的jar包存放在仓库中,而项目中仅需放置jar包的坐标信息。这样,当需要...

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

    Maven的依赖管理遵循一些原则,如“最接近优先”规则,如果一个项目有两个或更多版本的相同依赖,Maven会优先选择离项目最近的依赖。此外,Maven还支持排除依赖,如果你不想引入某个特定的子依赖,可以通过...

    Java开发之Maven依赖管理入门带阿里云源

    适用人群:该教程适合软件开发人员、架构师以及对自动化构建和依赖管理感兴趣的IT专业人士。无论您是初学者还是有经验的Java开发者,都可以从中获益。 使用场景及目标:您可将此教程作为学习Maven的起点,理解其...

    ​实现maven项目中多版本依赖兼容使用解决方案

    Maven依赖管理遵循“传递性”原则,即项目可以直接依赖其他项目,间接依赖也会被自动引入。当出现相同类路径的冲突时,Maven会遵循“第一声明者优先”原则,即先声明的依赖版本优先。 2. **排除依赖(Exclusions)...

    maven依赖+继承+聚合

    在软件开发领域,Maven是一个广泛使用的项目管理和综合工具,主要负责构建、依赖管理和项目信息管理。本示例将深入探讨Maven中的“依赖”、“继承”和“聚合”这三个核心概念,帮助开发者更好地理解和应用Maven。 ...

    maven依赖包(用于博客项目)

    在Java开发领域,Maven是广泛使用的...综上所述,这个“maven依赖包(用于博客项目)”包含了构建博客应用所需的全部或部分关键库,通过Maven的依赖管理和构建机制,能够有效地组织和管理项目的复杂性,加速开发进程。

    Maven依赖包(用于博客项目)

    Maven依赖管理的核心在于它的`pom.xml`文件,这是一个项目对象模型(Project Object Model)的配置文件,记录了项目的所有依赖。通过在`pom.xml`中声明依赖,Maven可以自动下载并管理这些依赖,避免了手动下载JAR...

    doris-1.1.3源码编译broker-maven依赖包repository

    这个过程涉及到的知识点主要包括 Maven 的使用、源码编译流程以及依赖管理。 首先,让我们深入了解 Maven。Maven 是一个项目管理和综合工具,用于自动化构建、依赖管理和项目信息管理。在Doris中,Maven 负责管理...

    Geoserver maven 依赖

    在GIS(地理信息系统)领域,GeoServer是一款开源的、基于Java...这不仅简化了项目的构建过程,也使得依赖管理变得更加有序和高效。通过Maven,你可以轻松地集成和利用GeoServer的强大功能,构建出自己的地图服务应用。

    java-maven-ckfinder-2.3-jar包依赖

    总的来说,CKFinder 2.3 通过 Maven 依赖管理,简化了在 Java 项目中集成文件管理功能的过程。正确地添加和配置 CKFinder,可以让你的用户轻松地进行文件上传和管理,提高应用程序的用户体验。记得根据具体需求调整 ...

    maven 中引入依赖的包

    总的来说,Maven的依赖管理是其强大功能的一部分,它极大地简化了Java项目的构建流程,让开发者能够更专注于代码编写,而不是库的管理。通过熟练掌握Maven的依赖引入和管理,开发者可以更高效地进行项目开发和协作。

    maven依赖包2

    【标题】"maven依赖包2"涉及到的是Java开发中重要的构建工具——Maven的依赖管理部分。在Java世界里,Maven是一个广泛使用的项目管理和综合工具,它可以帮助开发者管理和构建Java项目,通过解决项目的依赖关系,使得...

Global site tag (gtag.js) - Google Analytics