spring-boot-starter-parent 是 spring boot 提供的 bom 父 pom,统一管理依赖版本、编译插件、资源过滤等默认配置;不继承它将导致依赖缺失、启动失败、java 版本错配等问题,需手动补全各项配置。

spring-boot-starter-parent 是什么,不继承会怎样
它不是必须的,但跳过它等于主动放弃 Spring Boot 最省心的一套默认配置。不继承 spring-boot-starter-parent,你得自己管版本对齐、插件配置、资源过滤、Java 编译级别——这些事它本可以默默帮你做完。
常见错误现象:mvn clean package 后生成的 jar 缺少依赖、@SpringBootApplication 启动失败报 NoClassDefFoundError、Maven 编译用的是 Java 1.8 却跑在 Java 17 上出问题。
- 它本质是一个 BOM(Bill of Materials),统一管理所有
spring-boot-starter-*及其传递依赖的版本 - 它预设了
maven-compiler-plugin的source和target(默认 Java 17,随 Spring Boot 版本变) - 它启用了
resources目录下的属性占位符过滤(比如${spring.profiles.active}能被正确替换)
想换父 POM 或多模块下怎么处理
有些项目已有顶层父 POM,不能直接继承 spring-boot-starter-parent;或者你用 Gradle,根本没 pom.xml。这时候不能硬套,得拆解它的能力再组合。
关键不是“要不要父 POM”,而是“哪些能力你真需要”。比如你只想要依赖版本管理,那引入 BOM 就够了:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 用
<scope>import</scope>引入spring-boot-dependencies(注意不是-starter-parent)才能生效 - 编译插件、资源过滤这些得自己补全,否则 profile 激活、
application.yml中的变量不会被替换 - 多模块项目中,只有 parent module 需要这样声明,子 module 不用重复
为什么改了 <java.version></java.version> 还是编译成旧版本
因为 spring-boot-starter-parent 里定义的 <java.version></java.version> 只是给 Maven 插件用的默认值,它本身不强制编译行为——真正起作用的是 maven-compiler-plugin 的配置,而这个插件的配置又依赖于 parent 是否被继承。
如果你看到 mvn compile 输出里还是 Source level: 1.8,说明插件没加载到 parent 的配置。
- 检查是否真的继承了
spring-boot-starter-parent(<parent></parent>标签存在且坐标正确) - 确认没有在子 module 中覆盖
<properties></properties>里的java.version,但忘了同步更新插件配置 - 执行
mvn help:effective-pom看最终生效的插件配置,比猜更准
starter-parent 里藏了哪些容易被忽略的默认行为
它悄悄做了几件事,平时不报错,一出问题就难定位:比如测试资源不打包、YAML 文件不被过滤、甚至某些 IDE 导入后 classpath 顺序异常。
-
src/test/resources默认不参与最终 jar 构建(避免测试配置泄露),但如果你手动加了<resources></resources>块却没排除它,就可能混进去 -
application.properties和application.yml支持@..@占位符,但前提是maven-resources-plugin开启了filtering——这步由 parent 提供,自定义 parent 时极易漏掉 - 它把
spring-boot-maven-plugin设为默认,所以mvn spring-boot:run才能直接用;换掉 parent 后,这个命令会报 “goal not found”
最麻烦的不是功能缺失,而是这些默认行为彼此耦合:改一个,可能连带影响 profile 激活、日志配置加载、甚至 Actuator 端点路径。别急着删 parent,先搞清你到底在动哪一根线。










