【Maven】依赖、继承、聚合

POM 依赖

Maven 解析依赖信息时,会到本地仓库中查找被依赖的 jar 包。

  • groupid:公司火组织域名倒序 + 项目名
  • artifactid:模块名
  • version:版本
  • scope:依赖的范围主要分为以下三种
    • complie:编译阶段(默认
      • 对主程序是否有效:√
      • 对测试程序是否有效:√
      • 是否参与打包:√
    • test:测试阶段
      • 对主程序是否有效:×
      • 对测试程序是否有效:√
      • 是否参与打包:×

        测试通过了才打包,所以不需要打包测试程序。

      • 典型例子:junit
    • provided:提供运行阶段(仅仅用来提供给运行)(代表目标环境已提供)
      • 对主程序是否有效:√
      • 对测试程序是否有效:√
      • 是否参与打包:×
      • 是否参与部署:×
      • 典型例子:servlet-api.jar
        > 如 servlet-api一般tomcat里面都会自带,所以把scope调成provided,目标环境已提供,打包的时候就不用带上servlet-api了。
  • exclusions:排除某个已有依赖。

依赖管理

Maven 一个核心的特性就是依赖管理。当我们处理多模块的项目(包含成百上千个模块或者子项目),模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。

可传递性依赖发现
一种相当常见的情况,比如说 A 依赖于其他库 B。如果,另外一个项目 C 想要使用 A ,那么 C 项目也需要使用库 B。

Maven 可以避免去搜索所有所需库的需求。Maven 通过读取项目文件(pom.xml),找出它们项目之间的依赖关系。

我们需要做的只是在每个项目的 pom 中定义好直接的依赖关系。其他的事情 Maven 会帮我们搞定。

类比:比如高等数学的建立依赖于初等数学,而我们解题需要用到高等数学的知识,那么我们只需要导入高等数学即可,其他的初等数学的知识 Maven 会帮我们导入。
解题需要依赖高等数学,高等数学需要依赖初等数学,这就是一个传递依赖,我们只需要将项目的直接依赖写入,其他的所需的传递依赖,Maven 会顺着直接依赖往下不断地导入依赖。

通过可传递性的依赖,所有被包含的库的图形会快速的增长。当有重复库时,可能出现的情形将会持续上升。Maven 提供一些功能来控制可传递的依赖的程度。

功能 功能描述 备注
依赖调节 决定当多个手动创建的版本同时出现时,哪个依赖版本将会被使用。 如果两个依赖版本在依赖树里的深度是一样的时候,第一个被声明的依赖将会被使用。
依赖管理 直接的指定手动创建的某个版本被使用。 例如当一个工程 C 在自己的依赖管理模块包含工程 B,即 B 依赖于 A, 那么 A 即可指定在 B 被引用时所使用的版本。
依赖范围 包含在构建过程每个阶段的依赖。
依赖排除 任何可传递的依赖都可以通过 "exclusion" 元素被排除在外。 举例说明,A 依赖 B, B 依赖 C,因此 A 可以标记 C 为 "被排除的"。
依赖可选 任何可传递的依赖可以被标记为可选的,通过使用 "optional" 元素。 例如:A 依赖 B, B 依赖 C。因此,B 可以标记 C 为可选的, 这样 A 就可以不再使用 C。

依赖范围(scope)

传递依赖发现可以通过使用如下的依赖范围来得到限制:

范围 描述 备注
编译阶段(complie) 该范围表明相关依赖是只在项目的类路径下有效。默认取值。 编译时需要用到的依赖
供应阶段(provided) 该范围表明相关依赖是由运行时的 JDK 或者 网络服务器提供的。 JRE 运行环境需要提供的依赖
运行阶段 该范围表明相关依赖在编译阶段不是必须的,但是在执行阶段是必须的。
测试阶段(test) 该范围表明相关依赖只在测试编译阶段和执行阶段。 测试时需要用到的依赖
系统阶段 该范围表明你需要提供一个系统路径。
导入阶段 该范围只在依赖是一个 POM 里定义的依赖时使用。同时,当前项目的 POM 文件的 部分定义的依赖关系可以取代某特定的 POM。
    <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。 -->
    <dependencies>
        <dependency>
            <!--依赖的group ID -->
            <groupId>org.apache.maven</groupId>
            <!--依赖的artifact ID -->
            <artifactId>maven-artifact</artifactId>
            <!--依赖的版本号。 在Maven 2里,也可以配置成版本号的范围。 -->
            <version>3.8.1</version>
            <!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应, 
                尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为 true,就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。 -->
            <type>jar</type>
            <!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成 
                JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件。 -->
            <classifier></classifier>
            <!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。 - compile :默认范围,用于编译 - provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath 
                - runtime: 在执行时需要使用 - test: 用于test任务时使用 - system: 需要外在提供相应的元素。通过systemPath来取得 
                - systemPath: 仅用于范围为system。提供相应的路径 - optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用 -->
            <scope>test</scope>
            <!--仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。 -->
            <systemPath></systemPath>
            <!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题 -->
            <exclusions>
                <exclusion>
                    <artifactId>spring-core</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
            <!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。 -->
            <optional>true</optional>
        </dependency>
    </dependencies>

依赖的原则

(自己编写的工程,依赖相当于 import)

  • 作用:解决模块工程之间的 jar 包冲突问题。
  • 原则:
    • 路径最短者优先
    • 路径相同时,先声明者优先

      先声明指的是 dependency 标签的声明顺序。

继承

  • 现状:需要统一管理依赖
    Hello 依赖的 junit:4.0
    HelloFriend 依赖的 junit:4.0
    MakeFriends 依赖的 junit:4.9
    由于 test 范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致。
  • 需求:统一管理各个模块工程中对 junit 依赖的版本
  • 解决思路:将 junit 依赖统一提取到“父”工程中,在子工程中声明 junit 依赖时不指定版本,以父工程中统一设定的为准。同时也便于修改。
  • 操作步骤:
    1. 创建一个 Maven 工程作为父工程。

      注意:打包的方式 pom,只是一个整合的 maven 文件,不需要写程序

    2. 在子工程中声明对父工程的引用
    3. 将子工程的坐标中与父工程坐标中重复的内容删除
    4. 在父工程中统一 junit 的依赖
    5. 在子工程中删除 junit 依赖的版本号部分

聚合

聚合可以在父工程中写。
在 Maven 中的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可。

  • 作用:一键安装各个模块工程
  • 配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块。
  • 使用方式:在聚合工程的 pom.xml 上点右键→run as→maven install
<modules>
    <!-- 交换顺序不影响聚合 -->
    <module>../Hello</module>
    <module>../HelloFriend</module>
    <module>../MakeFriends</module>
</modules>

作用

  1. 项目中定义的依赖信息都可以在父工程进行定义,子模块不需要定义依赖信息,直接继承过来即可
  2. 将各个子模块聚合在一起
  3. 将父工程保存到maven本地仓库(注意:别忘了这一步)

Maven 库站

我们可以到 http://mvnrepository.com/ 搜索需要的 jar 包的依赖信息。

推荐配置方式

  1. 使用 properties 标签内使用自定义标签统一声明版本号,以便于版本的更新。

    类比:宏定义常量。
    xml <properties> <spring.version>4.0.0.RELEASE</spring.version> </properties>

  2. 在需要统一版本的威兹,使用\({自定义标签名}引用声明的版本号 ```xml <version>\){spring.version}
    ```

其实 properties 标签配合自定义标签声明数据的配置并不是只能用于声明依赖的版本号。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本篇文章和大家了解一下怎么搭建maven私有仓库。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。在本篇文章中,我们将介绍如何搭建一个Maven...
今天小编给大家分享的是如何解决Maven依赖冲突,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。目...
这篇文章主要介绍了Maven仓库分类的优先级是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Maven仓库分类的优先级是什么文...
本篇内容主要讲解“Maven怎么实现自己的starter依赖”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Maven怎
本篇内容主要讲解“maven不能下载oraclejdbc驱动的问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大...
这篇文章主要介绍了怎么使用maven基本命令打包包名的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用maven基本命令打包包...
本篇内容介绍了“maven中profile如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本文小编为大家详细介绍“Maven打包没有指定主类问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“Maven打包没有指定主类问题怎么解决”文章能帮助...
这篇文章主要介绍“maven怎么打包动态环境变量”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“maven怎么打包动态环...
今天小编给大家分享一下Maven离线模式打包的步骤是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考
本文小编为大家详细介绍“maven打包时候修改包名称带上git版本号和打包时间的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“maven打包时候修改包...
这篇文章主要讲解了“maven打包怎么指定jdk的版本”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“maven打...
这篇“Maven打包时怎么指定启动类”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读
这篇文章主要讲解了“怎么使用jenkins配置maven和JDK”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎
这篇文章主要介绍了maven中配置项目的jdk版本无效怎么排查的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇maven中配置项目的jdk...
今天小编给大家分享一下Maven提示jdk版本不正确怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考
本篇内容主要讲解“maven优缺点及使用方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“maven优缺点
这篇文章主要介绍“maven项目引入maven库没有jar怎么处理”,在日常操作中,相信很多人在maven项目引入maven库没有jar怎么处理问题上存在疑惑,小编查阅了各式资...
本篇内容主要讲解“怎么下载远程maven仓库的jar并手动放到本地仓库”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学...
这篇文章主要介绍“maven私服搭建与使用的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“maven私服搭建...