当前位置: 首页 > ops >正文

Maven中的bom和父依赖

maven最全避坑指南写完后,发现自己对于bom和父pom的理解还是不够深入,特此转载DeepSeek的回答,和大家一起学习了。

在 Maven 的依赖管理中,父 POM (Parent POM)BOM (Bill of Materials) 都是用于实现集中化管理和控制的核心机制,但它们的设计目的、工作方式和应用场景有显著区别:

核心区别总结表

特性父 POM (Parent POM)BOM (Bill of Materials)
主要目的定义和继承公共配置集中管理依赖版本
打包类型<packaging>pom</packaging><packaging>pom</packaging>
机制继承 (<parent>)导入 (<scope>import)
控制范围全局性 (构建配置、插件、依赖管理、属性等)针对性 (仅依赖版本管理)
强制性 (子模块自动继承大部分配置) (项目需显式导入才生效)
灵活性较低 (子模块可能被迫继承不需要的配置)较高 (项目可选择性地导入所需 BOM)
典型内容属性、依赖管理、插件管理、仓库、报告配置等几乎只有 <dependencyManagement>
适用场景紧密耦合的多模块项目松散耦合的项目、微服务架构、第三方平台集成

详细解释

  1. 父 POM (Parent POM)

    • 核心机制:继承 (<parent> 标签)
      • 子模块 POM 文件通过 <parent> 元素声明其父 POM。
      • 子模块继承父 POM 中定义的大部分内容:
        • <properties>:定义的属性(如 Java 版本、编码、依赖版本号属性)。
        • <dependencyManagement>:依赖版本和范围的管理(子模块声明依赖时不需要写版本)。
        • <pluginManagement>:插件版本和配置的管理(子模块声明插件时通常不需要写版本)。
        • <repositories> / <pluginRepositories>:仓库配置。
        • <build> / <reporting>:构建和报告的基础配置(如资源过滤、默认插件执行)。
        • <modules>:定义子模块列表(只在顶级父 POM 中使用)。
    • 目的:一组紧密相关的子模块(通常在一个多模块项目中)提供统一的基础配置和默认行为,确保构建一致性,减少重复配置。
    • 强制性: 强。子模块一旦声明了父 POM,就必须遵守父 POM 中定义的大部分规则(尤其是依赖管理和插件管理)。父 POM 像是一个“宪法”。
    • 灵活性: 相对较低。如果父 POM 定义了一个插件配置或依赖管理项,所有子模块都会继承它,即使某个子模块不需要。子模块可以覆盖父 POM 的配置,但需谨慎。
    • 典型结构:
      <!-- 父 pom.xml -->
      <project><modelVersion>4.0.0</modelVersion><groupId>com.company</groupId><artifactId>parent-project</artifactId><version>1.0.0</version><packaging>pom</packaging> <!-- 关键! --><modules><module>service-a</module><module>service-b</module></modules><properties><java.version>17</java.version><spring-boot.version>3.1.0</spring-boot.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope> <!-- 父POM也可以导入BOM! --></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.2-jre</version></dependency></dependencies></dependencyManagement><build><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version></plugin><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>
      </project><!-- 子模块 pom.xml -->
      <project><modelVersion>4.0.0</modelVersion><parent><groupId>com.company</groupId><artifactId>parent-project</artifactId><version>1.0.0</version></parent><artifactId>service-a</artifactId><dependencies><dependency> <!-- 版本由父POM的dependencyManagement控制 --><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency></dependencies><build><plugins><plugin> <!-- 版本由父POM的pluginManagement控制 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
      </project>
      
  2. BOM (Bill of Materials)

    • 核心机制:导入 (<scope>import)
      • BOM 本身是一个特殊的 POM 文件 (<packaging>pom</packaging>)。
      • 它的核心内容几乎只有 <dependencyManagement> 部分,其中精确定义了一组相关依赖及其允许的版本
      • 其他项目(可以是独立的项目,也可以是子模块)在自己的 <dependencyManagement> 部分中,通过 <scope>import</scope> 导入 BOM。
    • 目的: 专门且集中地管理一组第三方依赖的兼容版本。它本身不提供构建配置、插件管理或属性定义(虽然技术上可以放,但不推荐,违背单一职责)。它定义了一份“物料清单”。
    • 强制性: 弱。一个项目选择导入某个 BOM,才会受到其依赖版本管理的约束。项目可以导入多个 BOM。
    • 灵活性: 高。项目可以自由选择导入哪些 BOM(例如,核心平台 BOM、数据库 BOM、特定框架 BOM)。BOM 只影响依赖版本,不强制其他构建配置。
    • 典型结构:
      <!-- BOM pom.xml -->
      <project><modelVersion>4.0.0</modelVersion><groupId>com.company</groupId><artifactId>platform-bom</artifactId><version>2024.04.0</version><packaging>pom</packaging> <!-- 关键! --><dependencyManagement><dependencies> <!-- 核心:定义依赖和版本 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId><version>3.1.0</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.2-jre</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope> <!-- 甚至可以在BOM中建议scope --></dependency></dependencies></dependencyManagement><!-- 通常没有build/reporting/modules等部分 -->
      </project><!-- 使用BOM的项目 pom.xml (可以是独立项目或子模块) -->
      <project><modelVersion>4.0.0</modelVersion><groupId>com.company.service</groupId><artifactId>order-service</artifactId><version>1.0.0</version><dependencyManagement><dependencies><dependency> <!-- 导入BOM --><groupId>com.company</groupId><artifactId>platform-bom</artifactId><version>2024.04.0</version><type>pom</type><scope>import</scope> <!-- 关键!导入依赖管理 --></dependency></dependencies></dependencyManagement><dependencies><dependency> <!-- 声明依赖,不指定版本 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency></dependencies><!-- 项目自身的其他配置... -->
      </project>
      

关键区别点强调

  1. 机制与范围:

    • 父 POM 通过继承传递广泛的配置(依赖管理、插件管理、属性、仓库、构建配置等)。
    • BOM 通过导入传递单一的配置(依赖管理,主要是版本和 scope)。
  2. 耦合度:

    • 父 POM 创建了强耦合。子模块必须属于同一个父项目结构,并且继承父的“全部遗产”(可能包含不需要的东西)。
    • BOM 创建了弱耦合。任何项目(无论是否在同一个多模块结构中,甚至在不同仓库中)都可以选择导入一个或多个 BOM,仅获取其依赖版本定义。
  3. 职责:

    • 父 POM 是项目结构的管理者,定义整个项目或一组模块的构建基线和默认行为。
    • BOM 是依赖版本的协调者,专注于确保一组库在一起使用时版本的兼容性和一致性。

如何选择?结合使用!

在大型分布式系统或复杂的多模块项目中,最佳实践通常是结合使用两者,发挥各自优势:

  1. 创建顶级父 POM (可选但推荐):

    • 定义全局属性(Java 版本、编码、基础属性)。
    • 配置企业级仓库 (<repositories>, <pluginRepositories>)。
    • 管理基础插件的版本和配置 (<pluginManagement>)。
    • 管理非常核心、平台级依赖的版本(如公司内部基础库)。
    • 声明子模块 (<modules>)。
  2. 创建核心 BOM (强烈推荐):

    • 集中管理所有第三方库及其兼容版本。
    • 可以按领域创建多个 BOM(如 platform-bom, database-bom, observability-bom)。
  3. 在父 POM 中导入 BOM:

    <!-- 在父POM的dependencyManagement中 -->
    <dependencyManagement><dependencies><dependency><groupId>com.company</groupId><artifactId>platform-bom</artifactId><version>2024.04.0</version><type>pom</type><scope>import</scope> <!-- 将BOM的依赖管理导入到父POM --></dependency></dependencies>
    </dependencyManagement>
    
    • 这样子模块在继承父 POM 时,自动获得了 BOM 中定义的依赖版本控制。
    • 避免了在每个子模块中重复导入 BOM。
  4. 在独立项目/服务中使用 BOM:

    • 对于不在同一个父 POM 下的微服务或独立项目,直接在它们的 <dependencyManagement> 中导入所需的 BOM。

总结:

  • 父 POM = 构建配置的继承者 + 基础依赖管理者 + 项目结构组织者。 用于统一紧密相关模块的构建环境。
  • BOM = 依赖版本的权威清单。 用于跨项目(无论是否同构)统一第三方依赖版本,确保兼容性。
  • 最佳实践: 在分布式系统中,BOM 是管理依赖版本一致性的基石。父 POM 可以作为组织多模块项目和导入 BOM 的有效载体。两者协同工作,共同实现高效、一致、安全的依赖管理。
http://www.xdnf.cn/news/16450.html

相关文章:

  • [Linux]线程池
  • 【免费可用】【提供源代码】对YOLOV11模型进行剪枝和蒸馏
  • 跨境协作系统文化适配:多语言环境下的业务符号隐喻与交互习惯
  • Java项目:基于SSM框架实现的社区团购管理系统【ssm+B/S架构+源码+数据库+毕业论文+答辩PPT+远程部署】
  • Nuxt3 全栈作品【通用信息管理系统】修改密码
  • 亚远景-“过度保守”还是“激进创新”?ISO/PAS 8800的99.9%安全阈值之争
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博文章数据可视化分析-点赞区间实现
  • 【HTTP】防XSS+SQL注入:自定义HttpMessageConverter过滤链深度解决方案
  • 【数据标注】详解使用 Labelimg 进行数据标注的 Conda 环境搭建与操作流程
  • 572. 另一棵树的子树
  • 电子签章(PDF)
  • 【0基础PS】PS工具详解--选择工具--对象选择工具
  • 【Linux | 网络】传输层(UDP和TCP) - 两万字详细讲解!!
  • 利用软件定义无线USRP X410、X440 电推进无线原型设计
  • ksql连接数据库免输入密码交互
  • 设计模式(十四)行为型:职责链模式详解
  • 飞牛NAS本地化部署n8n打造个人AI工作流中心
  • 【Java系统接口幂等性解决实操】
  • SpringSecurity实战:核心配置技巧
  • 记录几个SystemVerilog的语法——时钟块和进程通信
  • 盛最多水的容器-leetcode
  • 洛谷 P10446 64位整数乘法-普及-
  • 详解力扣高频SQL50题之1164. 指定日期的产品价格【中等】
  • 3,Windows11安装docker保姆级教程
  • LeetCode 76:最小覆盖子串
  • mybatis的insert(pojo),会返回pojo吗
  • Petalinux生成文件的关系
  • 力扣面试150题--二进制求和
  • mmap机制
  • 2.qt调试日志输出