4-ysyThread-starter 模块设计-01
starter 模块设计-01
1 | . |
SpringBoot Starter 是什么
在传统开发中我们要使用某个框架功能(比如数据库访问或消息队列),常常需要东拼西凑地添加一堆依赖,还要配置各种参数。这就像下厨做菜前,还得 满世界找食材、调料,步骤繁琐又容易出错。而
Spring Boot Starter(启动器)就像一个贴心的“大厨助手”或 预先配好的料理包,帮我们一次性备齐所需“食材”(依赖)和默认配置,让开发者开箱即用
Starter 背景与作用
在没有
SpringBoot的年代,引入第三方组件通常意味着要在Maven/Gradle里添加多个坐标依赖,然后再去查文档写大量配置文件,非常麻烦(依赖版本不匹配、配置分散各处都是常见痛点)
SpringBoot 提出了“约定优于配置”的理念,Starters 正是这一理念的产物。Starter 的作用简单来说有以下几点:
1. 依赖管理一站式
一个 Starter 包含了一组相关的依赖,就像“自助套餐”。你加上一个 Starter,相当于引入了一系列经过官方测试搭配好的依赖,避免了自己挨个寻找版本兼容的库。不再需要东翻西找依赖,一个 Starter 就帮你打包好了所有常用库
2. 自动配置减负
Starter 配合 Spring Boot 的自动装配机制,能够根据类路径上的依赖自动进行默认配置。这意味着许多以前需要写的样板配置代码,现在 Spring Boot 会替你完成
3. 开箱即用的默认
大多数 Starter 都提供了一套合理的默认行为。例如 spring-boot-starter-logging 会默认使用 Logback 日志框架,spring-boot-starter-web 默认使用 Tomcat 容器并开启 Spring MVC。这些默认配置遵循官方最佳实践,避免了开发者从零开始配置
概括来说,
Spring Boot Starter的出现解决了依赖管理杂乱和配置碎片化的问题。过去可能我们需要拷贝粘贴各种依赖坐标、写很多配置,现在只需引入一个Starter,绝大部分配置就帮你默默搞定。这也是为什么Spring Boot能让项目搭建变得如此简单快速的关键原因之一
Starter 核心原理揭秘
Starters 之所以能做到“引入即用”,背后离不开 Spring Boot 自动装配(Auto-Configuration)机制 的支撑
Spring Boot 的启动流程
当我们在主应用类上标注了 @SpringBootApplication(其内部含有@EnableAutoConfiguration注解)时,Spring Boot 会在启动时做如下事情:
1. 搜集候选自动配置类
Spring Boot利用SpringFactoriesLoader去扫描应用类路径下所有JAR包里的特殊配置文件对于
Spring Boot 2.x,这个文件就是每个Starter JAR中META-INF/spring.factories而在
Spring Boot 3.x,这个机制有所改变,变成在每个Starter JAR中查找META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
2. 按条件装配自动配置类
拿到所有候选的自动配置类名后(可能成百上千个),SpringBoot 并不会傻乎乎地把它们统统装配进来,而是会挨个筛选,判断条件是否满足。这得益于 SpringBoot 提供的一系列条件注解
@ConditionalOnClass:当类路径下存在某个类时才生效@ConditionalOnMissingClass:缺少某类时生效@ConditionalOnBean:当容器中已有某个Bean时/不在时生效@ConditionalOnProperty:当配置文件中某个属性有指定值时生效等等
3. 注册 Bean 到容器
通过条件筛选后,符合条件的自动配置类会被实例化并发挥作用。其实每个自动配置类本质上就是一个加了 @Configuration 注解的普通 Spring 配置类,其中定义了一系列 @Bean 方法用于注册组件
至此,原本我们需要手工配置的许多 Bean,因为 Starter 的引入而在后台自动完成注册了
最小可运行的自定义 Starter 示例
假设我们要封装一个自定义的 HelloService,它提供一个 sayHello() 方法返回问候语。我们希望通过 Starter 来自动配置这个服务,并让使用者开箱即用地获得 HelloService
1. 核心功能代码
首先,我们编写 HelloService 及其自动配置类:
1 | // 提供简单业务功能的服务类 |
HelloAutoConfiguration 自动装配类:
1 | // 自动配置类,将 HelloService 注册为 Bean |
这里我们用了 @ConditionalOnMissingBean,确保如果用户自己已经提供了一个名为 helloService 的Bean,我们的默认配置就不重复注册,保持 SpringBoot 一贯的可扩展性。另外,在实际场景中,我们可能会为 HelloService 提供可配置的属性(比如问候语内容可配置)。这时可以引入 @ConfigurationProperties 注解的属性类,并在自动配置时通过 @EnableConfigurationProperties 注册它,从而让用户在 application.yml 里配置参数。例如我们可以有:
1 |
|
2. 注册自动配置
有了上面的自动配置类,接下来需要让 Spring Boot 在启动时知道它的存在。
在 Spring Boot 2.x 中
我们会在 META-INF/spring.factories 写入:
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.starter.HelloAutoConfiguration |
在 Spring Boot 3.x 中
则应该在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件里加入配置类全名,如:
1 | com.example.starter.HelloAutoConfiguration |
把这一行添加到 .imports 文件后,我们的 Starter 打包发布时就携带了自动配置声明。Spring Boot 应用在引入该 Starter 后,会扫描到这条声明并据此加载 HelloAutoConfiguration
3. 发布与依赖声明
当我们的 Starter 编写完毕并发布到仓库后,其他人要使用就非常简单了——就和使用官方 Starter 差不多。在他们的 SpringBoot 项目的 pom.xml 中引入依赖:
1 | <dependency> |
实际的坐标应以发布到仓库的为准(一般指的是 公司内部私有仓库),如果是一个开源项目(Maven 中央仓库)








