Spring Boot - Starter 机制
Spring Boot 核心 —— Starter 机制
1. 核心理论:什么是 Starter?
Starter,即“启动器”,是 Spring Boot 提供的一系列“一站式”依赖描述符。它本身通常不包含代码,主要是一个 Maven POM 文件,但它将构建特定类型应用所需的所有依赖都打包在了一起,并内置了默认的、经过测试的、兼容的版本。
-
核心思想: 简化依赖管理。开发者不再需要自己去寻找和管理大量的、可能存在版本冲突的依赖,只需要引入一个对应的 Starter,就能获得所需的一切。
-
生活比喻:
- 没有 Starter: 你想自己组装一台电脑。你需要自己去研究 CPU、主板、内存条、显卡、电源等所有配件的型号,并确保它们之间互相兼容。这个过程非常复杂,且容易出错。
- 有 Starter: 你去品牌电脑店,直接买一个“电竞主机”套装 (
spring-boot-starter-web) 或者“商务办公”套装 (spring-boot-starter-data-jpa)。这个套装里已经为你搭配好了所有兼容的、性能最佳的配件,你只需要把它抱回家,插上电就能用。
2. 深度剖析:Starter 与自动配置的关系
Starter 和自动配置是相辅相成的,它们共同构成了 Spring Boot 的核心魔法。
- Starter: 负责“引入依赖”。它把所有需要的“积木”(jar 包)都帮你搬到项目里。
- 自动配置: 负责“拼装积木”。它看到项目里有了这些“积木”,就按照预设的“图纸”(
@ConditionalOnClass等条件),自动把它们组装起来。
工作流程:
- 你在
pom.xml中引入spring-boot-starter-web。 - Maven 根据这个 Starter,自动下载了
spring-webmvc,spring-web,tomcat-embed,jackson-databind等一系列依赖。 - Spring Boot 应用启动时,
@EnableAutoConfiguration开始工作。 WebMvcAutoConfiguration这个自动配置类,通过@ConditionalOnClass检测到Servlet,DispatcherServlet等类存在于类路径下。- 条件满足,
WebMvcAutoConfiguration生效,自动为你配置DispatcherServlet等所有 Spring MVC 相关的 Bean。
3. 如何自定义一个 Starter?
理解 Starter 最好的方式,就是亲手做一个。自定义一个 Starter 通常遵循“三步走”的规范。
假设我们要创建一个 zhaowumian-spring-boot-starter,它能自动配置一个 GreetingService,并允许用户在 application.yml 中配置问候语。
第一步:创建 ...-spring-boot-autoconfigure 模块
这个模块负责编写自动配置的逻辑。
-
创建配置属性类 (
GreetingProperties.java)@ConfigurationProperties(prefix = "greeting") public class GreetingProperties { private String message = "Hello"; // 默认值 // Getters and Setters } -
创建业务服务类 (
GreetingService.java)public class GreetingService { private GreetingProperties properties; public GreetingService(GreetingProperties properties) { this.properties = properties; } public String greet() { return properties.getMessage() + ", World!"; } } -
创建自动配置类 (
GreetingAutoConfiguration.java)@Configuration @EnableConfigurationProperties(GreetingProperties.class) // 启用配置属性类 @ConditionalOnClass(GreetingService.class) // 条件:当GreetingService类存在时 @ConditionalOnProperty(prefix = "greeting", name = "enabled", havingValue = "true", matchIfMissing = true) // 条件:当配置greeting.enabled=true时,或没有配置时 public class GreetingAutoConfiguration { @Bean @ConditionalOnMissingBean // 条件:当容器中没有GreetingService的Bean时 public GreetingService greetingService(GreetingProperties properties) { return new GreetingService(properties); } } -
创建
spring.factories文件
在src/main/resources/META-INF/目录下创建spring.factories文件,内容如下:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.study.starter.GreetingAutoConfiguration这个文件就是用来告诉 Spring Boot:“嘿,我这里有一个自动配置类,你启动时记得加载它!”
第二步:创建 ...-spring-boot-starter 模块
这个模块是“空”的,它不包含任何代码,只有一个 pom.xml 文件,它的唯一作用就是管理依赖。
<project ...>
<artifactId>zhaowumian-spring-boot-starter</artifactId>
<dependencies>
<!-- 这个 Starter 会自动传递对 autoconfigure 模块的依赖 -->
<dependency>
<groupId>com.study</groupId>
<artifactId>zhaowumian-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
第三步:在其他项目中使用我们的 Starter
-
在你的 Spring Boot 项目的
pom.xml中,引入我们刚刚创建的 Starter:<dependency> <groupId>com.study</groupId> <artifactId>zhaowumian-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency> -
在
application.yml中进行配置:
greeting:
message: "Hi"
```
- 在代码中直接注入并使用
GreetingService:@RestController public class MyController { @Autowired private GreetingService greetingService; @GetMapping("/greet") public String greet() { return greetingService.greet(); // 输出 "Hi, World!" } }
通过这三步,我们就实现了一个功能完整的自定义 Starter。它遵循了 Spring Boot 的所有核心原则:依赖管理、自动配置、按需加载和用户优先。
4. Q&A
为什么要把 autoconfigure 和 starter 分成两个模块?
这是 Spring Boot 官方推荐的最佳实践,核心是为了关注点分离 (Separation of Concerns)。
autoconfigure模块: 只包含自动配置的核心逻辑代码,不依赖任何具体的项目。starter模块: 不包含任何代码,它是一个纯粹的“依赖描述符”,负责将autoconfigure模块以及其他可能需要的第三方库(如spring-web等)打包在一起。
这样做的好处是,用户只需要引入一个干净的 starter 依赖,就能获得所有功能,而无需关心底层的自动配置细节和复杂的依赖关系。
@ConditionalOnMissingBean 在这里起到了什么关键作用?
它起到了“用户优先”的关键作用,是 Spring Boot “约定优于配置”思想的重要体现。
- 作用: 它允许用户通过在自己的项目里定义一个同类型的 Bean(比如自己写一个
GreetingService并加上@Bean注解),来覆盖我们 Starter 中提供的默认 Bean。 - 效果: 当 Spring 容器中已经存在一个
GreetingService类型的 Bean 时,@ConditionalOnMissingBean的条件不满足,我们GreetingAutoConfiguration中的那个@Bean方法就不会被执行。这使得我们的 Starter 在提供便利的同时,又不失灵活性,用户可以随时接管配置。

浙公网安备 33010602011771号