一句话定位:Starter 是 Spring Boot 的依赖套餐(Dependency Descriptor)——引入一个 Starter(如
spring-boot-starter-web),即可获得该功能领域所需的全套兼容依赖,无需手动挑选和逐个引入。
定义与作用
Starter 是一组预定义的 Maven 依赖描述符,它将某个功能领域(如 Web 开发、数据访问、安全认证)所需的所有 JAR 打包成一个统一的入口。开发者只需在 pom.xml 中引入一个 Starter,Maven 的传递依赖机制会自动拉取该 Starter 声明的所有依赖。
它解决的痛点:
| 传统 Maven 项目 | 引入 Starter 后 |
|---|---|
手动引入 spring-webmvc、jackson-databind、hibernate-validator、tomcat-embed-core,逐个对齐版本 | 引入 spring-boot-starter-web 一个依赖,自动获得上述全部 |
版本冲突时逐个排查 spring-webmvc 依赖哪个 jackson | BOM 已锁定兼容版本,传递依赖自动解析 |
| 新成员加入项目时问:"这个项目需要哪些依赖?" | 看 pom.xml 中的 Starter 列表即可,语义清晰 |
升级 Spring 版本时,逐个修改 spring-webmvc、spring-jdbc 等版本号 | 升级 spring-boot-starter-parent 的版本号即可,所有 Starter 同步升级 |
适用位置与常用属性
Starter 是Maven 依赖,出现在 pom.xml 的 <dependencies> 节点中,无需写 version(由父 POM 的 BOM 锁定)。
常用 Starter 列表(飞翔科技常用)
| Starter | 包含的核心依赖 | 场景 | 自动配置效果 |
|---|---|---|---|
spring-boot-starter | Spring Boot 核心 + 自动配置 + 日志(logback + SLF4J) | 所有 Starter 的基座 | 提供日志和基本基础设施 |
spring-boot-starter-web | Spring MVC + Tomcat + Jackson + Validation | 传统 Web 应用 | 自动启动 Tomcat、注册 DispatcherServlet、配置 Jackson |
spring-boot-starter-webflux | Spring WebFlux + Reactor Netty | 响应式 Web 应用 | 自动启动 Netty、配置 RouterFunction |
spring-boot-starter-data-jpa | Hibernate + Spring Data JPA + HikariCP | JPA 数据访问 | 自动创建 EntityManagerFactory、JpaTransactionManager |
spring-boot-starter-jdbc | JdbcTemplate + HikariCP | JDBC 数据访问 | 自动创建 DataSource、JdbcTemplate |
spring-boot-starter-data-redis | Lettuce + Spring Data Redis | Redis 缓存 | 自动创建 RedisConnectionFactory、StringRedisTemplate |
spring-boot-starter-security | Spring Security | 安全认证授权 | 自动创建安全过滤器链,默认保护所有端点 |
spring-boot-starter-test | JUnit 5 + Mockito + AssertJ + Hamcrest | 单元/集成测试 | 提供 @SpringBootTest 和测试切片 |
spring-boot-starter-actuator | Actuator + Micrometer | 运维监控 | 自动暴露 /actuator/health、/actuator/metrics 等端点 |
spring-boot-starter-validation | Hibernate Validator | Bean 校验 | 自动配置 LocalValidatorFactoryBean |
spring-boot-starter-mail | JavaMail + Spring Mail | 邮件发送 | 自动创建 JavaMailSender |
spring-boot-starter-thymeleaf | Thymeleaf 模板引擎 | 服务端渲染 | 自动配置 Thymeleaf 视图解析器 |
命名规范
| 命名模式 | 说明 | 示例 |
|---|---|---|
spring-boot-starter-* | 官方 Starter,由 Spring 团队维护 | spring-boot-starter-web |
spring-boot-starter | 核心 Starter,无后缀,所有官方 Starter 的基座 | spring-boot-starter |
*-spring-boot-starter | 第三方 Starter,由社区或公司维护 | mybatis-spring-boot-starter |
核心原理
Starter 的依赖传递机制
层级解读:
- 本项目:小崔在
pom.xml中只写了spring-boot-starter-web和spring-boot-starter-jdbc两个依赖,都没有<version>。 - Starter 层:
spring-boot-starter-web是一个空 JAR(或极简 JAR),自身几乎无代码,它的作用是声明一组传递依赖——spring-webmvc、jackson-databind、hibernate-validator、spring-boot-starter-tomcat等。 - 核心库层:
spring-boot-starter-tomcat进一步传递依赖tomcat-embed-core和tomcat-embed-websocket。 - 版本来源:所有这些版本都不是小崔写的,而是由
spring-boot-dependenciesBOM 锁定(详见下一篇「BOM 版本管理」)。
引入 Starter 前后依赖数量对比
完整示例
场景说明
飞翔科技的学生成绩管理系统需要 Web 接口、JDBC 数据访问和运维监控。小崔对比了"手动引入依赖"和"使用 Starter"两种方案。
操作前:手动引入所有依赖(无 Starter)
<dependencies>
<!-- 手动引入 Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.27</version>
</dependency>
<!-- 手动引入 Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.5</version>
</dependency>
<!-- 手动引入 Tomcat -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.75</version>
</dependency>
<!-- 手动引入 JdbcTemplate -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.27</version>
</dependency>
<!-- 手动引入连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
<!-- 手动引入事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.27</version>
</dependency>
<!-- 手动引入 MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 手动引入 Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>2.7.18</version>
</dependency>
</dependencies>
问题:
- 8 个依赖,8 个版本号,任何一个升级都需要检查与其他依赖的兼容性。
- 新成员不知道
spring-webmvc和jackson-databind的版本是否匹配,容易引入冲突。 - 缺少
spring-webmvc的传递依赖(如spring-core、spring-context),需要进一步手动补齐。
使用 Starter 的完整代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
<groupId>com.feixiang</groupId>
<artifactId>student-management</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- Web 开发:Spring MVC + Tomcat + Jackson + Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JDBC 数据访问:JdbcTemplate + HikariCP + Transaction -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 运维监控:Actuator + Micrometer -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
传递依赖验证:
执行 mvn dependency:tree 查看实际解析的依赖树(节选):
com.feixiang:student-management:jar:1.0.0
+- org.springframework.boot:spring-boot-starter-web:jar:2.7.18:compile
| +- org.springframework.boot:spring-boot-starter:jar:2.7.18:compile
| | +- org.springframework.boot:spring-boot:jar:2.7.18:compile
| | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.7.18:compile
| | +- org.springframework.boot:spring-boot-starter-logging:jar:2.7.18:compile
| | | +- ch.qos.logback:logback-classic:jar:1.2.12:compile
| | +- org.springframework:spring-core:jar:5.3.27:compile
| +- org.springframework.boot:spring-boot-starter-json:jar:2.7.18:compile
| | +- com.fasterxml.jackson.core:jackson-databind:jar:2.13.5:compile
| | +- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.13.5:compile
| +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.7.18:compile
| | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.75:compile
| | +- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.75:compile
| +- org.springframework:spring-webmvc:jar:5.3.27:compile
| | +- org.springframework:spring-aop:jar:5.3.27:compile
| | +- org.springframework:spring-beans:jar:5.3.27:compile
| | +- org.springframework:spring-context:jar:5.3.27:compile
| | +- org.springframework:spring-expression:jar:5.3.27:compile
| +- org.springframework:spring-web:jar:5.3.27:compile
+- org.springframework.boot:spring-boot-starter-jdbc:jar:2.7.18:compile
| +- com.zaxxer:HikariCP:jar:4.0.3:compile
| +- org.springframework:spring-jdbc:jar:5.3.27:compile
| | +- org.springframework:spring-tx:jar:5.3.27:compile
+- mysql:mysql-connector-java:jar:8.0.33:runtime
+- org.springframework.boot:spring-boot-starter-actuator:jar:2.7.18:compile
+- io.micrometer:micrometer-core:jar:1.9.12:compile
操作后运行结果及分析
分析:
- 依赖数量:
pom.xml中只写了 5 个依赖,mvn dependency:tree实际解析出 30+ 个传递依赖,包括spring-core、spring-context、logback、jackson-core、tomcat-embed-websocket等,全部由 Starter 自动带入。 - 版本一致性:所有
org.springframework依赖都是5.3.27,所有jackson依赖都是2.13.5,所有tomcat依赖都是9.0.75,版本完全对齐,无冲突。 - 自动配置触发:
spring-boot-starter-web带入了spring-boot-autoconfigure,这是自动配置的引擎;spring-boot-starter-actuator带入了micrometer-core,这是指标采集的基础。 - 语义清晰:新人看
pom.xml,只看到web、jdbc、actuator等功能名称,无需关心底层库的具体坐标和版本。
白歌评价:"Starter 把'技术选型'变成了'功能点餐'。小崔不需要知道
jackson-databind的版本,他只需要说'我要 Web 功能'。"
易错场景与面试考点
易错场景:在 Starter 中手动写 version,导致版本冲突
小崔曾在一个已有 Spring Boot 的项目中,因为习惯使然,给某个依赖手动加了版本号。
错误示范:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.0</version> <!-- ← 错误:手动覆盖版本,与父POM 2.7.18 冲突 -->
</dependency>
后果:
- 父 POM 锁定的是
2.7.18的 Spring Boot 生态(Spring 5.3.27、Jackson 2.13.5)。 - 手动指定
2.6.0后,该 Starter 内部依赖的 Spring MVC 可能变成5.3.18,而其他 Starter(如spring-boot-starter-jdbc)仍由父 POM 锁定在 Spring 5.3.27。 - 结果:运行时出现
NoSuchMethodError或ClassNotFoundException,因为 Spring 5.3.18 和 5.3.27 的某些内部类签名不同。
正确做法:信任父 POM 和 BOM,不在 Starter 上写 version。如果确实需要升级 Spring Boot 版本,统一修改父 POM 的 <version>:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
面试考点
Q:Starter 的本质是什么?它里面有没有代码?
Starter 的本质是依赖描述符(Dependency Descriptor),通常是一个空 JAR 或只包含
META-INF/spring.provides的极简 JAR。它的核心作用是声明一组传递依赖,让开发者通过"引入一个依赖"获得"全套功能"。真正的代码在 Starter 传递依赖的底层库中(如spring-webmvc、jackson-databind)。
Q:自定义 Starter 需要遵循哪些命名规范?
官方 Starter 命名:
spring-boot-starter-*(如spring-boot-starter-web)。第三方 Starter 命名:*-spring-boot-starter(如mybatis-spring-boot-starter),避免与官方命名空间冲突。自定义 Starter 需要创建META-INF/spring.factories文件注册自动配置类。
Q:如何查看一个 Starter 具体引入了哪些依赖?
执行
mvn dependency:tree查看完整的依赖树。或者打开本地 Maven 仓库中该 Starter 的 POM 文件(如~/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.7.18/spring-boot-starter-web-2.7.18.pom),阅读其<dependencies>节点。
Q:如果只想用 Spring Boot 的版本管理,但不想继承 spring-boot-starter-parent(比如公司已有自己的父POM),怎么办?
可以使用
<dependencyManagement>导入spring-boot-dependenciesBOM,而非继承父 POM:<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>这样可以在不继承
spring-boot-starter-parent的情况下,获得 BOM 的版本锁定能力。但会丢失父 POM 提供的插件配置(如spring-boot-maven-plugin的默认绑定),需要手动配置。