Maven继承与聚合详解及作用介绍

作者:mzz124 时间:2023-03-08 00:14:36 

一、继承

引言

继承关系可以对不同模块的依赖版本做统一管理,因为子模块中的依赖基本都继承于父模块,父模块中指定哪个版本,子模块就继承哪个版本,可以有效避免不同模块可能采用不同版本的依赖时产生的冲突

1. 继承关系的实现

(1)parent 模块设置

parent 模块即父模块,由于父模块只是为了给子模块提供依赖,所以父模块中只需要一个 pom.xml 文件即可。父模块的打包方式必须设置为 pom(默认打包方式是 jar)

<groupId>com.mzz</groupId>
   <artifactId>parent-maven</artifactId>
   <version>1.0-SNAPSHOT</version>
   <!-- 设置打包方式为 pom -->
   <packaging>pom</packaging>

只要设置了 packaging 属性为 pom,这个模块就可以作为 parent 模块被继承了

(2)子模块设置

子模块中只要设置了 parent 标签,就可以建立继承关系。

所以继承主要体现在子模块,parent 模块是感受不到继承关系的,也无法从 parent 模块中看出哪些模块继承了自己。

另外继承关系建议以后,如果子模块与父模块处于同一 groupId 下,那么子模块可以不写 groupId

<!--<groupId>com.mzz</groupId>-->
   <artifactId>project-dao</artifactId>
   <version>1.0-SNAPSHOT</version>
<parent>
<!-- parent 模块的坐标与版本 -->
<groupId>com.mzz</groupId>
<artifactId>parent-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- parent 模块的相对路径 -->
<relativePath>../parent-maven/pom.xml</relativePath>
</parent>

对 relativePath 属性做一些补充:

  • relativePath 可以省略,前提是 parent 模块已经 install 至仓库,否则子模块无法定位到 parent,不能通过编译

  • 相对路径最后可以不写 pom.xml,只定位到父模块的文件夹也可以

2. 依赖配置

(1)必须继承的依赖

parent 模块中声明的依赖便是子模块必须继承的依赖,子模块中不必声明便从父模块中继承了这些依赖

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.20.RELEASE</version>
</dependency>
<!-- 省略了其他依赖的声明 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope><!-- scope 属性也会被继承 -->
</dependency>
<dependencies>

Maven继承与聚合详解及作用介绍

如上图,可见子模块中未声明依赖就继承了 parent 中的所有依赖

(2)有选择地继承依赖

parent 模块中设置依赖管理 dependencyManagement 后,在其中声明的依赖就是供子模块选择的依赖。子模块需要哪些依赖,必须在子模块中声明依赖,但不需要注明 version,因为版本由 parent 来指定。

<!-- parent 模块 -->
<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-test</artifactId>
           <version>5.2.10.RELEASE</version>
           <scope>test</scope>
       </dependency>
   </dependencies>
</dependencyManagement>
<!-- 子模块声明依赖 -->
<dependencies>
   <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
   </dependency>
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
   </dependency>
</dependencies>

如果子模块声明的依赖有 version 属性,那么这个依赖并不继承自 parent

另外,parent 模块声明在 dependencyManagement 中的依赖并不被 parent 模块所依赖

(3)插件继承

插件的继承规则和设置方法与前面的依赖极为相似,同样也有插件管理 pluginManagement,与 dependencyManagement 类似,这里给出一个 parent 中设置的样例模板

<build>
   <plugins>
<!-- 声明必须继承的插件 -->
   </plugins>
   <pluginManagement>
       <plugins>
<!-- 声明可供选择是否继承的插件 -->
       </plugins>
   </pluginManagement>
</build>

二、聚合

引言

聚合就是指将多个模块组织成一个整体,同时进行项目的构建工作。

使用聚合可以避免分模块开发时的一些问题,比如某个模块更新了一些内容,但其它已经构建好的模块不会进行更新,将所有模块聚合之后,只对聚合模块进行构建就会对所有模块都进行构建,能够及时的发现问题

实现聚合

聚合模块也被称为 root 模块,同样是一个只需要 pom.xml 文件的项目,只要设置了 modules 标签,再将聚合的模块添加进去,即可实现聚合

<modules>
<!-- module 属性中写明被聚合模块的相对路径 -->
<module>../project-pojo</module>
<module>../project-dao</module>
<module>../project-service</module>
</modules>

如上例,将 pojo,dao 和 service 三个模块进行了聚合,只要对聚合模块进行构建,这三个模块也会被一起构建

聚合只体现在聚合模块,被聚合的模块也无法感知自身被谁所聚合

三、继承与聚合的合并

继承是的 parent 模块和聚合时的 root 模块都只有 pom.xml,因为他们都是设计型模块,不包含实际的模块内容。事实上,继承与聚合经常被合并在一起使用,父模块(parent)也作为聚合模块(root)使用,只需要在父模块中加入 modules 属性,将子模块聚合即可

这时要说一说继承时说到的 relativePath 属性,前面说 relativePath 属性可以省略,前提是父模块已经构建并 install 至仓库,否则子模块无法构建,但此时父模块同时也聚合了子模块,要构建父模块就又要一起构建子模块,但构建子模块又需要父模块 install 至仓库&hellip;&hellip;陷入了套娃问题

此时构建父模块 maven 会报错: Non-resolvable parent POM for XXX.XXX.XXX Could not find artifact com.mzz:parent-maven:pom:1.0-SNAPSHOT and &lsquo;parent.relativePath&rsquo; points at wrong local POM,原因是无法定位 parent 模块

解决方法也很简单,要么老老实实在子模块中 parent 标签中加入 relativePath 属性,使 maven

可以根据相对路径找到父模块,要么,先将父模块中的 modules 注释掉,暂时不做聚合,将父模块 install 之后再取消注释,然后就能一起构建啦

来源:https://blog.csdn.net/Cey_Tao/article/details/126567296

标签:Maven,继承,聚合
0
投稿

猜你喜欢

  • 模仿美团点评的Android应用中价格和购买栏悬浮固定的效果

    2021-11-12 12:00:42
  • java使用软引用实现缓存机制示例

    2021-08-26 18:06:12
  • SpringBoot启动自动终止也不报错的原因及解决

    2023-01-16 02:15:40
  • Java实现对两个List快速去重并排序操作示例

    2023-05-02 03:40:14
  • mybatis中数据加密与解密的实现

    2022-04-21 22:49:16
  • 利用logback 设置不同包下的日志级别

    2022-08-11 20:05:43
  • Android广播接实现监听电话状态(电话的状态,拦截)

    2022-12-21 18:50:49
  • C# WinForm RichTextBox文本动态滚动显示文本方式

    2021-09-12 20:44:31
  • Android 中无法取消标题栏的问题小结(两种方法)

    2021-06-25 19:45:02
  • Java RandomAccessFile 指定位置实现文件读取与写入

    2023-06-05 17:06:25
  • java中使用数组进行模拟加密的方法

    2023-11-18 15:37:39
  • C# Path类---文件路径解读

    2022-05-20 05:58:47
  • Mybatis之#{}与${}的区别使用详解

    2023-03-24 01:55:21
  • Java中通过jsch来连接远程服务器执行linux命令

    2023-02-02 22:21:52
  • 详解WPF中用户控件和自定义控件的使用

    2023-07-25 12:20:26
  • c# Struct的一些问题分析

    2023-08-31 08:27:36
  • java 中clone()的使用方法

    2023-03-31 12:11:37
  • SpringBoot中获取profile的方法详解

    2023-11-19 18:05:00
  • 逆波兰计算器(Java实现)

    2021-10-18 09:45:01
  • android studio 安装完成ButterKnife插件却无法使用(解决方案)

    2023-03-14 17:54:58
  • asp之家 软件编程 m.aspxhome.com