【Maven】 的继承机制

Maven是一个强大的项目管理工具,主要用于Java项目的构建和管理。它以其项目对象模型(POM)为基础,允许开发者定义项目的依赖、构建过程和插件。Maven的继承机制是其核心特性之一,它允许子项目继承和复用父项目的配置,从而提高了代码重用性和管理的简洁性。

在本篇文章中,我们将详细讲解Maven的继承机制,包括继承的基本概念、继承的实现方式以及一些常见的应用场景。

一、Maven继承的基本概念

1.1 POM文件

在Maven中,项目对象模型(POM,Project Object Model)是项目的核心配置文件,位于项目根目录的pom.xml文件中。POM文件定义了项目的基本信息、依赖、插件、构建配置等。

一个典型的POM文件结构如下:

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>my-project</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><!-- 依赖声明 --></dependencies><build><plugins><!-- 插件声明 --></plugins></build></project>

1.2 继承的作用

Maven继承机制允许子项目从父项目继承POM配置。这意味着子项目可以复用父项目的依赖、插件、构建配置等,避免了重复定义。

继承的主要作用有:

  • 配置复用:子项目可以继承父项目的依赖、插件、构建配置等,从而减少重复配置。
  • 集中管理:可以在父项目中集中管理公共依赖和配置,方便版本的统一升级和维护。
  • 模块化开发:支持多模块项目的管理,每个子项目可以有自己的特定配置。

1.3 Maven继承的局限性

  • 单一继承:Maven不支持多继承,每个子项目只能有一个直接的父项目。
  • 继承与聚合的混淆:有时候开发者会将继承与聚合混淆,需要明确它们的区别。

二、Maven继承的实现

Maven继承通过父子关系实现。子项目通过指定父项目的groupIdartifactIdversion来建立继承关系。

2.1 创建父项目

首先,我们需要创建一个父项目,定义公共的POM配置。

父项目POM (parent-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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><properties><!-- 公共属性 --><java.version>17</java.version><spring.version>5.3.12</spring.version></properties><dependencyManagement><dependencies><!-- 公共依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency></dependencies></dependencyManagement><build><plugins><!-- 公共插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></build></project>

2.2 创建子项目

接下来,我们创建一个子项目,并让其继承父项目的POM配置。

子项目POM (child-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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>child-project</artifactId><dependencies><!-- 子项目特有的依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency></dependencies></project>

2.3 执行Maven命令

在根目录下执行mvn clean install,Maven会自动处理父子关系,并构建整个项目。

2.4 查看继承效果

当子项目继承父项目后,子项目的构建将使用父项目中定义的依赖和插件配置:

  • 子项目会自动使用父项目中的spring-context依赖。
  • 子项目会自动使用父项目中的maven-compiler-plugin插件,Java版本为17。

子项目的有效POM

我们可以通过Maven命令查看子项目的有效POM(Effective POM),它展示了继承后的最终配置。

执行以下命令:

mvn help:effective-pom

在终端输出中,可以看到子项目的完整POM配置,包括从父项目继承的部分。

三、Maven继承中的常用元素

3.1 dependencyManagement

  • 作用:用于在父项目中定义依赖的版本管理。
  • 特点:子项目继承时,不会自动引入依赖,而是只继承版本信息。

示例

<dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency></dependencies>
</dependencyManagement>

子项目使用时只需引用依赖,而不需要显式指定版本:

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><!-- 版本号已由父项目管理 --></dependency>
</dependencies>

3.2 pluginManagement

  • 作用:用于在父项目中定义插件的版本管理。
  • 特点:子项目继承时,不会自动引入插件,而是只继承版本信息。

示例

<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></pluginManagement>
</build>

子项目需要手动引入插件:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId></plugin></plugins>
</build>

3.3 properties

  • 作用:用于在父项目中定义全局属性,子项目可以继承并使用这些属性。
  • 示例
<properties><java.version>17</java.version><spring.version>5.3.12</spring.version>
</properties>

子项目使用属性:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins>
</build>

3.4 buildprofiles

  • 作用:定义构建过程中的配置和多环境配置。
  • 示例
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.0.0-M5</version></plugin></plugins>
</build><profiles><profile><id>development</id><properties><env>dev</env></properties></profile><profile><id>production</id><properties><env>prod</env></properties></profile>
</profiles>

子项目可以通过命令行参数激活特定配置:

mvn clean install -Pdevelopment

四、Maven继承与聚合的区别

Maven中的继承与聚合是两个不同的概念,容易混淆。

4.1 继承(Inheritance)

  • 特点
    • 父子项目有继承关系。
    • 子项目继承父项目的POM配置。
  • 用途
    • 适用于需要共享公共配置的项目。

4.2 聚合(Aggregation)

  • 特点
    • 父项目是一个容器项目,没有实际业务逻辑。
    • 父项目通过modules元素管理多个子模块。
  • 用途
    • 适用于多模块项目的管理。

4.3 继承与聚合同时使用

在实际项目中,继承和聚合可以同时使用,以实现更高效的项目管理。

示例

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>multi-module-project</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>module-a</module><module>module-b</module></modules><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.12</version></dependency></dependencies></dependencyManagement></project>

模块A的POM

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>multi-module-project</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>module-a</artifactId><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency></dependencies></project>

模块B的POM

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>multi-module-project</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>module-b</artifactId><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency></dependencies></project>

五、Maven继承的高级应用

5.1 多层继承

Maven支持多层继承,即子项目可以继续充当父项目,提供更深层次的继承结构。

parent-pom├── intermediate-pom│     ├── child-a│     └── child-b└── child-c

中间层POM

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>intermediate-project</artifactId><dependencyManagement><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency></dependencies></dependencyManagement></project>

子项目A的POM

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>intermediate-project</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>child-a</artifactId><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency></dependencies></project>

5.2 使用自定义的父POM

在某些情况下,我们可能需要自定义一个父POM,用于管理公司的多个项目。

  • 创建一个company-parent-pom,其中包含公司标准的依赖、插件和构建配置。
  • 每个项目都可以继承这个company-parent-pom,实现标准化的项目管理。

公司父POM

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.company</groupId><artifactId>company-parent-pom</artifactId><version>1.0</version><packaging>pom</packaging><properties><java.version>17</java.version></properties><dependencyManagement><dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.1</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></build></project>

项目POM

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.company</groupId><artifactId>company-parent-pom</artifactId><version>1.0</version></parent><artifactId>my-company-project</artifactId><dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId></dependency></dependencies></project>

5.3 使用parent.relativePath实现跨项目继承

在多模块项目中,子项目默认会在相对路径上寻找父项目。但在某些情况下,我们希望子项目引用远程仓库中的父POM,而不是本地的父POM。这时可以使用parent.relativePath属性。

<parent><groupId>com.company</groupId><artifactId>company-parent-pom</artifactId><version>1.0</version><relativePath/> <!-- 设置为空,强制从远程仓库获取 -->
</parent>

六、常见问题与解决方案

6.1 子项目不继承父项目的依赖版本

问题:子项目引用父项目的依赖时,需要手动指定版本号。

解决方案:确保依赖被定义在dependencyManagement中,而不是dependencies中。

6.2 多模块项目构建失败

问题:在多模块项目中,某个子模块构建失败导致整个项目构建失败。

解决方案:可以使用-pl参数单独构建某个模块:

mvn clean install -pl module-a

6.3 父子项目之间版本不兼容

问题:子项目与父项目使用的依赖版本不一致,导致冲突。

解决方案:可以在子项目中覆盖父项目的依赖版本:

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.15</version> <!-- 覆盖版本 -->
</dependency>

七、总结

Maven的继承机制是项目管理中的一个重要特性,它通过父子关系实现配置复用、集中管理和模块化开发。在实际应用中,我们可以结合继承和聚合机制,实现更高效的项目管理。

关键点回顾

  • Maven的POM文件是项目配置的核心。
  • 子项目通过parent元素继承父项目的配置。
  • dependencyManagementpluginManagement用于管理依赖和插件的版本。
  • 继承与聚合是Maven中两个不同的概念,但可以结合使用。
  • 通过多层继承和自定义父POM实现更复杂的项目管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/50575.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能算法驱动的爬虫平台:解锁网络数据的无限潜力

摘要 在信息爆炸的时代&#xff0c;网络数据如同深海宝藏&#xff0c;等待着有识之士发掘其无尽价值。本文将探索智能算法驱动的爬虫平台如何成为解锁这一宝库的关键&#xff0c;不仅剖析其技术优势&#xff0c;还通过实例展示它如何助力企业与开发者高效、稳定地采集数据&…

数据结构之树知识总结

数据结构之树知识总结 树型结构&#xff1a; 1、树的基本概念 ​ 一种表示层次关系(一对多)的数据节构 ​ 有且只有一个特定的节点&#xff0c;该节点没有前趋节点&#xff0c;被称为根节点 ​ 剩余的n个互不相交的子集&#xff0c;其中每个子集也都是一棵树&#xff0c;都被…

C语言 ——— 数组指针的定义 数组指针的使用

目录 前言 数组指针的定义 数组指针的使用 前言 之前有编写过关于 指针数组 的相关知识 C语言 ——— 指针数组 & 指针数组模拟二维整型数组-CSDN博客 指针数组 顾名思义就是 存放指针的数组 那什么是数组指针呢&#xff1f; 数组指针的定义 何为数组指针&#xf…

【QT】UDP

目录 核心API 示例&#xff1a;回显服务器 服务器端编写&#xff1a; 第一步&#xff1a;创建出socket对象 第二步&#xff1a; 连接信号槽 第三步&#xff1a;绑定端口号 第四步&#xff1a;编写信号槽所绑定方法 第五步&#xff1a;编写第四步中处理请求的方法 客户端…

JAVA开发工具IDEA如何连接操作数据库

一、下载驱动 下载地址&#xff1a;【免费】mysql-connector-j-8.2.0.jar资源-CSDN文库 二、导入驱动 鼠标右击下载到IDEA中的jar包&#xff0c;选择Add as Library选项 如图就导入成功 三、加载驱动 Class.forName("com.mysql.cj.jdbc.Driver"); 四、驱动管理…

最新站长工具箱源码,拥有几百个功能,安装教程

最新站长工具箱源码&#xff0c;拥有几百个功能&#xff0c;安装教程 在 Docker 上运行 docker run -e LAFREGIONCN -e APPLANGzh_CN --name my-miaoda -v ~/.miaoda-docker:/root/.miaoda -d -p 0.0.0.0:39899:39899 codegentoolbox/laftools-linux-x64:latestNOTE: 默认端…

【C++】——红黑树(手撕红黑树,彻底弄懂红黑树)

目录 前言 一 红黑树简介 二 为什么需要红黑树 三 红黑树的特性 四 红黑树的操作 4.1 变色操作 4.2 旋转操作 4.3 插入操作 4.4 红黑树插入代码实现 4.5 红黑树的删除 五 红黑树迭代器实现 总结 前言 我们之前都学过ALV树&#xff0c;AVL树的本质就是一颗平…

计算机实验室排课查询小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#xff0c;取消预约管理&#xff0c;实验课程管理&#xff0c;实验报告管理&#xff0c;报修信息管理&#xff0…

【Python】如何在 Python 中操作 Excel

Python 操作 Excel 文件 1. 常用的几种库 xlrd和xlwt库 xlrd&#xff1a;用于读取Excel文件。xlwt&#xff1a;用于写入Excel文件。这两个库通常一起使用&#xff0c;xlrd用于读取&#xff0c;xlwt用于写入&#xff0c;但它们不支持Excel 2007及以后的.xlsx格式。 openpyxl库…

Linux的yum源安装MySQL5.7

linux的yum源安装MySQL5.7 一、MySQL 1、简介 MySQL 是一种流行的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典公司 MySQL AB 开发&#xff0c;后来被 Oracle Corporation 收购。它是一个开源软件&#xff0c;提供了高效、稳定和可靠的数据管理解决…

【Spring Framework】Spring 事务使用的完整示例

为了详细展示 Spring 事务的使用&#xff0c;我将提供一个完整的示例&#xff0c;包括配置、代码和说明。这将涵盖以下几个方面&#xff1a; 数据库配置&#xff1a;包括数据源和事务管理器的配置。实体类&#xff1a;用于数据库操作的数据模型。DAO 层&#xff1a;数据访问对…

Android SurfaceFlinger——GraphicBuffer的提交(三十三)

在 SurfaceFlinger 中,我们 dequeueBuffer 和 queueBuffer 是 Surface 控制接口中非常重要的两个函数,分别用于从 Surface 的 BufferQueue 中取出缓冲区和向 BufferQueue 提交(队列)缓冲区。这两个函数在生产者和消费者模型中扮演着核心角色,确保了图像数据的高效和有序传…

消息队列原理题库

1. 简述什么是消息队列 &#xff1f; 消息&#xff08;Message&#xff09;是指在应用间传送的数据。消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。 消息队列&#xff08;Message Queue&#xff09;是一种应用间…

【算法】子集

难度:中等 题目: 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 示例 2: 输入…

Spring AI (三) 提示词对象Prompt

3.提示词对象Prompt 3.1.Prompt Prompt类的作用是创建结构化提示词, 实现了ModelRequest<List<Message>>接口 Prompt(String contents)&#xff1a;创建一个包含指定内容的Prompt对象。 Prompt(String contents, ChatOptions modelOptions)&#xff1a;创建一个…

某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC]

文章目录 某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内…

DolphinDB Web 端权限管理:可视化操作指南

在现代数据库管理中&#xff0c;高效和直观的权限管理对于用户的数据安全是至关重要的。过去 DolphinDB 用户需要依赖系统脚本来管理用户和权限&#xff0c;这对于缺乏技术背景的管理员来说既复杂又容易出错。 为了提升用户体验和操作效率&#xff0c;DolphinDB 目前在 Web 上…

数据库设计三范式

文章目录 数据库设计三范式第一范式第二范式第三范式一对一怎么设计主键共享外键唯一 一对多怎么设计多对多怎么设计 数据库设计三范式 数据库表设计的原则。教你怎么设计数据库表有效&#xff0c;并且节省空间。 如果客户有速度要求极致&#xff0c;可以不用。根据客户需求来 …

vue3中动态添加form表单校验

<template><div><div v-for"(formData, index) in forms" :key"index"><u-form :model"formData" :rules"rules" ref"formRefs"><u-form-item label"用户名" prop"username"…

MySQL数据库练习(5)

1.建库建表 # 使用数据库 use mydb16_trigger;# 表格goods create table goods( gid char(8) primary key, name varchar(10), price decimal(8,2), num int);# 表格orders create table orders( oid int primary key auto_increment, gid char(10) not null, name varchar(10…