Maven(下):依赖管理、依赖传递、依赖冲突、工程继承及工程聚合

1. 基于IDEA 进行Maven依赖管理

1.1 依赖管理概念

Maven 依赖管理是 Maven 软件中最重要的功能之一。Maven 的依赖管理能够帮助开发人员自动解决软件包依赖问题,使得开发人员能够轻松地将其他开发人员开发的模块或第三方框架集成到自己的应用程序或模块中,避免出现版本冲突和依赖缺失等问题。

我们通过定义 POM 文件,Maven 能够自动解析项目的依赖关系,并通过 Maven 仓库自动下载和管理依赖,从而避免了手动下载和管理依赖的繁琐工作和可能引发的版本冲突问题。

总之,Maven 的依赖管理是 Maven 软件的一个核心功能之一,使得软件包依赖的管理和使用更加智能和方便,简化了开发过程中的工作,并提高了软件质量和可维护性。

1.2 Maven工程核心信息配置和解读(GAVP)

位置:pom.xml


<modelVersion>4.0.0modelVersion>

<groupId>com.companyname.project-groupgroupId>

<artifactId>projectartifactId>

<version>1.0.0version>


<packaging>jar/pom/warpackaging>

1.3 Maven工程依赖管理配置

位置:pom.xml

依赖管理和依赖添加


<dependencies>
    
    <dependency>
        <groupId>log4jgroupId>
        <artifactId>log4jartifactId>
        <version>1.2.17version>
        
        <scope>runtimescope>
    dependency>

dependencies>

依赖版本统一提取和维护


<properties>
  
  <junit.version>4.12junit.version>
  
  <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
properties>

<dependencies>
  <dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    
    <version>${junit.version}version>
  dependency>
dependencies>

1.4 依赖范围

通过设置坐标的依赖范围(scope),可以设置对应jar包的作用范围:编译环境、测试环境、运行环境

依赖范围 描述
compile 编译依赖范围,scope 元素的缺省值。使用此依赖范围的 Maven 依赖,对于三种 classpath 均有效,即该 Maven 依赖在上述三种 classpath 均会被引入。例如,log4j 在编译、测试、运行过程都是必须的。
test 测试依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath 有效。例如,Junit 依赖只有在测试阶段才需要。
provided 已提供依赖范围。使用此依赖范围的 Maven 依赖,只对编译 classpath 和测试 classpath 有效。例如,servlet-api 依赖对于编译、测试阶段而言是需要的,但是运行阶段,由于外部容器已经提供,故不需要 Maven 重复引入该依赖。
runtime 运行时依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath、运行 classpath 有效。例如,JDBC 驱动实现依赖,其在编译时只需 JDK 提供的 JDBC 接口即可,只有测试、运行阶段才需要实现了 JDBC 接口的驱动。
system 系统依赖范围,其效果与 provided 的依赖范围一致。其用于添加非 Maven 仓库的本地依赖,通过依赖元素 dependency 中的 systemPath 元素指定本地依赖的路径。鉴于使用其会导致项目的可移植性降低,一般不推荐使用。
import 导入依赖范围,该依赖范围只能与 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencyManagement 的配置导入合并到当前 pom.xml 的 dependencyManagement 中。

主要的三种依赖范围为complie、test、provided。

2. ## Maven依赖传递和依赖冲突

2.1 Maven依赖传递特性

概念

假如有Maven项目A,项目B依赖A,项目C依赖B。那么我们可以说 C依赖A。也就是说,依赖的关系为:C—>B—>A, 那么我们执行项目C时,会自动把B、A都下载导入到C项目的jar包文件夹中,这就是依赖的传递性。

作用

  • 简化依赖导入过程
  • 确保依赖版本正确

传递的原则

在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围以及配置

  • B 依赖 C 时使用 compile 范围:可以传递

  • B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

  • B 依赖 C 时,若配置了以下标签,则不能传递

    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>druidartifactId>
        <version>1.2.15version>
        <optional>trueoptional>
    dependency>
    

依赖传递终止

  • 非compile范围进行依赖传递
  • 使用optional配置终止传递
  • 依赖冲突(传递的依赖已经存在)

2.2 Maven依赖冲突特性

当直接引用或者间接引用出现了相同的jar包! 这时呢,一个项目就会出现相同的重复jar包,这就算作冲突!依赖冲突避免出现重复依赖,并且终止依赖传递!

maven自动解决依赖冲突问题能力,会按照自己的原则,进行重复依赖选择。同时也提供了手动解决的冲突的方式,不过不推荐!

解决依赖冲突(如何选择重复依赖)方式:

  • 自动选择原则

    • 短路优先原则(第一原则)

      A—>B—>C—>D—>E—>X(version 0.0.1)

      A—>F—>X(version 0.0.2)

      则A依赖于X(version 0.0.2)。

    • 依赖路径长度相同情况下,则“先声明优先”(第二原则)

      A—>E—>X(version 0.0.1)

      A—>F—>X(version 0.0.2)

      中,先声明的,路径相同,会优先选择!

  • 手动排除

    <dependency>
      <groupId>org.kkk.mavengroupId>
      <artifactId>maven-javaartifactId>
      <version>1.0-SNAPSHOTversion>
      <scope>compilescope>
      
      <exclusions>
        
        <exclusion>
          
          <groupId>commons-logginggroupId>
          <artifactId>commons-loggingartifactId>
        exclusion>
      exclusions>
    dependency>
    

3. Maven工程继承和聚合

3.1 Maven工程继承

  • 继承概念

    Maven 继承是指在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。

  • 继承作用

    在父工程中统一管理项目中的依赖信息。

    它的背景是:

    • 对一个比较大型的项目进行了模块拆分。
    • 一个 project 下面,创建了很多个 module。
    • 每一个 module 都需要配置自己的依赖信息。

    它背后的需求是:

    • 在每一个 module 中各自维护各自的依赖信息很容易发生出入,不易统一管理。
    • 使用同一个框架内的不同 jar 包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一。
    • 使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
    • 通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将以往的经验沉淀下来,节约时间和精力。
  • 继承语法

    • 父工程

        <groupId>org.kkk.mavengroupId>
        <artifactId>maven-parentartifactId>
        <version>1.0-SNAPSHOTversion>
        
        <packaging>pompackaging>
      
      
    • 子工程

      
      <parent>
        
        <groupId>org.kkk.mavengroupId>
        <artifactId>maven-parentartifactId>
        <version>1.0-SNAPSHOTversion>
      parent>
      
      
      
      
      <artifactId>maven-moduleartifactId>
      
      
  • 父工程依赖统一管理

    • 父工程声明版本

      
      
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-coreartifactId>
            <version>6.0.10version>
          dependency>
          <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-beansartifactId>
            <version>6.0.10version>
          dependency>
          <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>6.0.10version>
          dependency>
          <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-expressionartifactId>
            <version>6.0.10version>
          dependency>
          <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aopartifactId>
            <version>6.0.10version>
          dependency>
        dependencies>
      dependencyManagement>
      
    • 子工程引用版本

      
      
      
      <dependencies>
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-coreartifactId>
        dependency>
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-beansartifactId>
        dependency>
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-contextartifactId>
        dependency>
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-expressionartifactId>
        dependency>
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-aopartifactId>
        dependency>
      dependencies>
      

3.2 Maven工程聚合

  • 聚合概念

    Maven 聚合是指将多个项目组织到一个父级项目中,以便一起构建和管理的机制。聚合可以帮助我们更好地管理一组相关的子项目,同时简化它们的构建和部署过程。简单地讲,将多个项目聚合到一个父级项目中,那么可以通过对父级项目进行构建达到同时构建多个子项目的效果。

  • 聚合作用

    • 管理多个子项目:通过聚合,可以将多个子项目组织在一起,方便管理和维护。
    • 构建和发布一组相关的项目:通过聚合,可以在一个命令中构建和发布多个相关的项目,简化了部署和维护工作。
    • 优化构建顺序:通过聚合,可以对多个项目进行顺序控制,避免出现构建依赖混乱导致构建失败的情况。
    • 统一管理依赖项:通过聚合,可以在父项目中管理公共依赖项和插件,避免重复定义。
  • 聚合语法

    父项目中包含的子项目列表。在父项目的modules模块中引入子项目的信息。

    <project>
      <groupId>com.examplegroupId>
      <artifactId>parent-projectartifactId>
      <packaging>pompackaging>
      <version>1.0.0version>
      <modules>
        <module>child-project1module>
        <module>child-project2module>
      modules>
    project>
    

你可能感兴趣的:(Maven,maven,java)