Maven dependencyManagement元素标签的具体使用

 更新时间:2024年03月28日 14:24:24   作者:懒鸟一枚  
在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器,本文主要介绍了Maven dependencyManagement元素标签的具体使用,感兴趣的可以了解一下

我们知道,子模块可以通过继承获得父模块中声明的全部依赖,这样虽然避免了在各个子模块 POM 中重复进行依赖声明,但也极有可能造成子模块中引入一些不必要的依赖。为此 Maven 引入了 dependencyManagement 来对依赖进行管理。

依赖管理

Maven 可以通过 dependencyManagement 元素对依赖进行管理,它具有以下 2 大特性:

  • 在该元素下声明的依赖不会实际引入到模块中,只有在 dependencies 元素下同样声明了该依赖,才会引入到模块中。
  • 该元素能够约束 dependencies 下依赖的使用,即 dependencies 声明的依赖若未指定版本,则使用 dependencyManagement 中指定的版本,否则将覆盖 dependencyManagement 中的版本。
    例如,修改 App-Data-lib 模块的 pom.xml 如下。
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--由于不是继承,所以必须重新添加 groupId 和 version-->
    <groupId>org.example</groupId>
    <artifactId>App-Data-lib</artifactId>
    <version>1.0</version>
    <!--dependencyManagement 标签用于控制子模块的依赖版本等信息 -->
    <!-- 该标签只用来控制版本,不能将依赖引入 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <!--引用的properties标签中定义的属性 -->
                <version>1.2.17</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <!--引用的properties标签中定义的属性 -->
                <version>4.9</version>
                <!-- <scope>test</scope> -->
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <!--引用的properties标签中定义的属性 -->
                <version>5.1.18</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <!--引用的properties标签中定义的属性 -->
                <version>0.9.1</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--声明依赖-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
</project>

在以上配置中,由于 dependencyManagement 元素中已经定义完整的依赖声明,所以在 dependencies 元素中声明的依赖只配置了 groupId 和 artifactId,省略了 version 和 scope。

在实际的开发过程中,dependencyManagement 很少会单独使用,通常它需要与 Maven 继承或依赖范围 import 配合使用才能展现它的优势。

继承依赖管理

由于 dependencyManagement 元素是可以被继承的,因此我们可以在父模块 POM 中使用 dependencyManagement 元素声明所有子模块的依赖,然后在各个子模块 POM 使用 dependencies 元素声明实际用到的依赖即可。这样既可以让子模块能够继承父模块的依赖配置,还能避免将不必要的依赖引入到子模块中。

1. 修改父模块 Root 的 pom.xml 如下。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>Root</artifactId>
    <version>1.0</version>
    <!--定义的父类pom.xml 打包类型使pom -->
    <packaging>pom</packaging>
    <properties>
        <!-- 定义一些 maven 变量 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <log4j.version>1.2.17</log4j.version>
        <junit.version>4.9</junit.version>
        <system.version>1.0</system.version>
        <mysql.connector.version>5.1.18</mysql.connector.version>
        <c3p0.version>0.9.1</c3p0.version>
    </properties>
    <!--dependencyManagement 标签用于控制子模块的依赖版本等信息 -->
    <!-- 该标签只用来控制版本,不能将依赖引入 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <!--引用的properties标签中定义的变量 -->
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <!--引用的properties标签中定义的变量 -->
                <version>${junit.version}</version>
                <!-- <scope>test</scope> -->
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <!--引用的properties标签中定义的变量 -->
                <version>${mysql.connector.version}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <!--引用的properties标签中定义的变量 -->
                <version>${c3p0.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

注:以上配置中,将所有依赖的版本信息以 Maven 变量(properties)的形式提取出来,这样不仅消除了一些重复,也使得各个依赖的版本信息更加明显,便于管理。

在父模块 Root 中使用 dependencyManagement 元素声明的依赖,既不会给 Root 模块引入依赖,也不会给其子模块引入依赖,但这段配置是可以被继承的。

2. 修改子模块 App-Core-lib 的 pom.xml 如下。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>App-Core-lib</artifactId>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>Root</artifactId>
        <version>1.0</version>
        <relativePath>../Root</relativePath>
    </parent>
    <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
        </dependency>
    </dependencies>
    <distributionManagement>
        <repository>
            <id>bianchengbang_Release_hosted</id>
            <url>http://localhost:8082/nexus/content/repositories/bianchengbang_Release_hosted/</url>
        </repository>
        <snapshotRepository>
            <id>Snapshot</id>
            <url>http://localhost:8082/nexus/content/repositories/bianchengbang_Snapshot_hosted/</url>
        </snapshotRepository>
    </distributionManagement>
</project>

在子模块 App-Core-lib 和 App-Data-lib 的 POM 中,所有在 dependencies 元素中声明的依赖都只配置了 groupId 和 artifactId,省去了 version 和 scope。之所以能够省略这些信息,是因为它们继承了父模块 Root 中 dependencyManagement 的配置,其完整的依赖声明已经包含在父模块的 POM 中,子模块只需要配置 groupId 和 artifactId 就能获得相应的依赖信息,从而引入正确的依赖。

使用这种依赖管理机制似乎并不能减少太多 POM 配置,但我们仍然推荐使用这种方式,其原因主要有 2 个:

-在父模块中使用 dependencyManagement 声明依赖能够统一项目内依赖的版本,子模块无须声明版本,也就不会出现多个子模块使用同一依赖项版本不一致的情况,降低依赖冲突的几率。

  • dependencyManagement 声明的依赖不会被实际引入,子模块需要什么依赖就自己引入,增加了灵活性,避免引入一些不必要的依赖。

导入依赖管理

因为 import 依赖范围只能与 dependencyManagement 元素配合使用才会有效,其功能是将目标 pom.xml 中的 dependencyManagement 配置导入合并到当前 pom.xml 的 dependencyManagement 中。

例如,App-Data-lib 模块想要使用 Root 模块中的 dependencyManagement 配置,除了通过继承或者直接复制这两种方式之外,还可以使用 import 依赖范围将其导入,具体配置如下。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--由于不是继承,所以必须重新添加 groupId 和 version-->
    <groupId>org.example</groupId>
    <artifactId>App-Data-lib</artifactId>
    <version>1.0</version>
    <!--定义依赖管理-->
    <dependencyManagement>
        <dependencies>
            <!--导入依赖管理配置-->
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>Root</artifactId>
                <version>1.0</version>
                <!--依赖范围为 import-->
                <scope>import</scope>
                <!--类型一般为pom-->
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--声明依赖-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
</project>


以上配置中,由于 import 依赖范围的特殊性,一般都是指向打包类型为 pom 的模块,所以 type 元素的值一般为 pom。

若存在多个模块,它们使用的依赖版本都是一致的,则就可以定义一个使用 dependencyManagement 专门管理依赖的 POM,然后在各个模块中导入这些依赖管理配置。

到此这篇关于Maven dependencyManagement元素标签的具体使用的文章就介绍到这了,更多相关Maven dependencyManagement内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • IDEA打包普通web项目操作

    IDEA打包普通web项目操作

    这篇文章主要介绍了IDEA打包普通web项目操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • java中HashSet的特点及实例用法

    java中HashSet的特点及实例用法

    在本篇文章里小编给大家整理的是一篇关于java中HashSet的特点及实例用法,有兴趣的朋友们可以学习下。
    2021-04-04
  • Java和C的随机数(Random)详解

    Java和C的随机数(Random)详解

    本篇文章主要介绍了Java和C随机数(Random),现在分享给大家,也给大家做个参考,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-09-09
  • SQLSyntaxErrorException-ExecutorException报错解决分析

    SQLSyntaxErrorException-ExecutorException报错解决分析

    这篇文章主要为大家介绍了SQLSyntaxErrorException-ExecutorException报错解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • SpringMVC RESTFul实现列表功能

    SpringMVC RESTFul实现列表功能

    这篇文章主要为大家介绍了SpringMVC RESTFul实现列表功能详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Mybatis-Plus同时使用逻辑删除和唯一索引的问题及解决办法(报数据重复Duplicate entry的问题)

    Mybatis-Plus同时使用逻辑删除和唯一索引的问题及解决办法(报数据重复Duplicate entry的

    在开发中,我们经常会有逻辑删除和唯一索引同时使用的情况,但当使用mybatis plus时,如果同时使用逻辑删除和唯一索引,会报数据重复Duplicate entry的问题,如何解决这个问题呢,小编给大家分享Mybatis-Plus同时使用逻辑删除和唯一索引的问题及解决办法,一起看看吧
    2023-11-11
  • Java中ThreadLocal的使用及原理详解

    Java中ThreadLocal的使用及原理详解

    这篇文章主要介绍了Java中ThreadLocal的使用及原理详解,ThreadLocal是JDK提供的,提供线程本地变量,主要用来存放线程独有变量和解决参数传递问题的,需要的朋友可以参考下
    2023-09-09
  • 简单了解Java垃圾回收器的种类

    简单了解Java垃圾回收器的种类

    这篇文章主要介绍了简单了解Java垃圾回收器的种类,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • 基于ReentrantLock的实现原理讲解

    基于ReentrantLock的实现原理讲解

    这篇文章主要介绍了ReentrantLock的实现原理,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Mybatis基于注解与XML开发使用流程

    Mybatis基于注解与XML开发使用流程

    MyBatis是Java的持久化框架,目的是为了使操作数据库更加方便、灵活、高效,可以通过Java注解和XML文件来映射Java对象和SQL语句,提供了非常灵活的SQL编写方式和动态SQL语句的创建方式,这篇文章主要介绍了Mybatis基于注解与XML开发,需要的朋友可以参考下
    2023-07-07

最新评论