为何以继承方式引入SpringBoot

在 Spring Boot 中,官方项目几乎都采用继承父 POM 的方式引入,即:

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
</parent>

这个设计不是偶然的,它解决了 Spring Boot 依赖管理中最核心的两个问题:版本统一 和插件预置。


版本统一:dependencyManagement

spring-boot-starter-parent 中定义了一个巨大的 <dependencyManagement>,锁定了数百个常用库的版本号------Spring 各模块、第三方库(如 Jackson、MyBatis、Hibernate)、数据库驱动等。子模块引入依赖时不需要写版本号,由父 POM 统一管理。

手动管理版本号时,经常出现 A 依赖需要 2.3.1 版本,B 依赖依赖 2.3.5 版本,两个库之间版本不匹配导致诡异报错。继承 starter-parent 后,Spring Boot 团队已经为所有 Starter 依赖完成了兼容性测试,你只需要关注功能,不需要操心版本之间的冲突。


插件预置:maven-plugin

spring-boot-maven-plugin 在父 POM 中已经配置好了。如果手动引入 Spring Boot,需要自己写这个插件的配置,包括 repackage 目标的绑定、mainClass 的指定等。继承父 POM 后,这些全有了,子模块不需要额外配置。


属性定制

父 POM 通过 <properties> 定义了 Java 版本、编码格式等常用属性。子模块可以覆盖这些属性,比如将 Java 版本从 8 改成 17,只需要在子 POM 中重新定义 java.version 即可。


使用场景的限制

继承方式有一个天然限制:Maven 只允许单继承 。如果项目已经继承了其他父 POM(比如公司内部的公共父 POM),就无法再继承 spring-boot-starter-parent。

这种情况下可以用 BOM(Bill of Materials)方式替代:

xml 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.7.18</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

BOM 方式只提供依赖版本管理,不提供插件预置。spring-boot-maven-plugin 需要在子模块中单独配置。两种方式的对比如下:

对比点 继承 parent BOM 导入
依赖版本管理 ✅ 有 ✅ 有
插件预置 ✅ 有 ❌ 需手动配置
Java 版本默认值 ✅ 有 ❌ 需手动设置
资源过滤默认配置 ✅ 有 ❌ 需手动配置
是否支持多继承 ❌ 单继承限制 ✅ 可多个 BOM 叠加

继承方式的本质

spring-boot-starter-parent 是一个标准的 Maven 父 POM,它自身又继承了 spring-boot-dependencies。前者负责插件配置和属性管理,后者负责依赖版本锁定。两层结构分离了"版本管理"和"构建配置"两个职责。

当你在子 POM 中声明一个依赖不写版本号时,Maven 会沿着父子链向上查找,最终在 spring-boot-dependencies 中找到对应的版本。当执行 mvn package 时,spring-boot-maven-plugin 会执行 repackage 目标,生成可执行的 Fat Jar。

继承方式让 Spring Boot 项目的 pom.xml 保持极简,你把核心精力放在业务依赖上,而不是构建配置的细节。这也是 Spring Boot "约定优于配置"理念在构建层面的体现。

相关推荐
程序猿DD5 小时前
OctaFuse Gateway 2.15.0:MCP 聚合、向量 Embeddings 与官方目录同步
后端·agent
蛋蛋的就会顺顺的7 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
余槐i7 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
需要8268 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡8 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
凤山老林9 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
伯恩bourne10 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
张彦峰ZYF10 小时前
停顿短不等于延迟低:G1、ZGC 与低延迟服务的目标分野、代价账本与选型标定
后端·回收暂停、应用停止总时长·到达安全点、分配停滞·屏障吃吞吐、并发线程吃核心·并发窗口吃堆余量·分区式靠挑回收集兑现目标·染色指针式不支持压缩引用
silvamux_10 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
pride.li10 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉