01 Starter 核心机制
SpringBoot 核心思想是约定大于配置,而 Starter 正是这一思想的核心落地载体。
简单来说,Starter 把某一类功能的依赖管理、默认配置、自动装配逻辑打包成一个独立 Jar 包。
项目只需引入这个 Jar 包,就能直接使用对应功能,无需关心底层依赖的具体版本、Bean 如何配置等细节。
02 Starter 开发规范
想要开发出符合 SpringBoot 生态、易维护的 Starter,需遵循以下核心规范:
02.1 命名规范
• 官方 Starter:统一采用 spring-boot-starter-* 命名格式,例如 spring-boot-starter-web。
• 第三方 Starter:推荐使用 xxx-spring-boot-starter 格式,例如 mybatis-spring-boot-starter。
02.2 版本管理规范
必须统一继承 spring-boot-dependencies BOM(物料清单),避免因依赖传递导致的版本冲突问题。
02.3 模块划分规范
合理的模块拆分能让 Starter 职责单一、支持可插拔,推荐拆分方式:
xxx-spring-boot-starter(空壳模块,仅做依赖聚合管理)
xxx-spring-boot-autoconfigure(核心模块,包含自动配置代码)
xxx-spring-boot-starter-core(可选模块,存放纯业务 API 逻辑)
02.4 自动配置类规范
SpringBoot 3.x 版本起,推荐使用 @AutoConfiguration 注解替代传统的 @Configuration 注解定义自动配置类。
02.5 条件注解规范
必须合理使用条件注解(如 @ConditionalOnClass、@ConditionalOnProperty、@ConditionalOnMissingBean),既能避免 Bean 重复装配,也能保证用户可自定义覆盖默认 Bean。
02.6 配置元数据规范
建议提供 spring-configuration-metadata.json 文件,辅助 IDE 实现配置项的自动提示,提升用户使用体验。
02.7 SPI 注册规范
自动配置类需要通过 SPI 机制让 SpringBoot 扫描到,不同版本配置方式不同:
• SpringBoot 3.x:配置文件路径 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。
• SpringBoot 2.x:配置文件路径 META-INF/spring.factories。
建议同时兼容两个版本的配置方式,提升 Starter 兼容性。
03 Starter 开发实战:以短信(SMS)功能为例
下面以企业常用的短信发送功能为例,完整演示 Starter 的开发流程。
本次实战将 Starter 拆分为两个核心模块:
• sms-spring-boot-autoconfigure:负责自动配置逻辑和核心业务实现。
• sms-spring-boot-starter:仅做依赖聚合管理,简化用户引入操作。
03.1 autoconfigure 模块开发
该模块是 Starter 的核心,包含配置项定义、核心功能实现、自动配置逻辑等。
(1)配置项类定义
用于绑定用户在配置文件中定义的短信相关配置,通过 @ConfigurationProperties 指定配置前缀。
java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 短信配置项类
* 绑定配置文件中以 "sms" 为前缀的配置项
*/
@Data // Lombok 注解,自动生成getter/setter/toString等方法
@ConfigurationProperties(prefix = "sms") // 指定配置前缀
public class SmsProperties {
// 短信功能总开关
private boolean enabled = true;
// 云厂商AccessKey(访问密钥)
private String accessKey;
// 云厂商SecretKey(密钥)
private String secretKey;
// 云厂商地域(如阿里云的cn-hangzhou)
private String region;
}
(2)核心功能接口与实现
定义短信发送的标准接口,以及阿里云短信的具体实现(可扩展其他厂商)。
java
import java.util.Map;
/**
* 短信发送模板接口
* 定义短信发送的标准方法,适配不同云厂商实现
*/
public interface SmsTemplate {
/**
* 发送短信
* @param mobile 接收短信的手机号
* @param sign 短信签名
* @param template 短信模板编码
* @param params 短信模板参数(如验证码、有效期等)
* @return 发送结果(自定义SendResult类,包含发送状态、回执ID等)
*/
SendResult send(String mobile, String sign, String template, Map<String,String> params);
}
/**
* 阿里云短信模板实现类
* 实现SmsTemplate接口,对接阿里云短信SDK
*/
public class AliyunSmsTemplate implements SmsTemplate {
// 注入短信配置项
private final SmsProperties smsProperties;
// 构造方法注入配置
public AliyunSmsTemplate(SmsProperties smsProperties) {
this.smsProperties = smsProperties;
// 初始化阿里云短信客户端(此处省略SDK初始化逻辑)
}
/**
* 实现短信发送方法
* @param mobile 手机号
* @param sign 短信签名
* @param template 模板编码
* @param params 模板参数
* @return 发送结果
*/
@Override
public SendResult send(String mobile, String sign, String template, Map<String, String> params) {
// 1. 构建阿里云短信请求参数
// 2. 调用阿里云短信SDK发送短信
// 3. 解析SDK返回结果,封装为SendResult返回
// 此处省略具体SDK调用逻辑,可参考阿里云官方文档
return new SendResult(true, "发送成功", System.currentTimeMillis() + "");
}
}
/**
* 短信发送结果封装类
* 简化示例,实际可扩展更多字段(如错误码、错误信息等)
*/
class SendResult {
// 是否发送成功
private boolean success;
// 提示信息
private String msg;
// 短信回执ID
private String bizId;
public SendResult(boolean success, String msg, String bizId) {
this.success = success;
this.msg = msg;
this.bizId = bizId;
}
// 省略getter/setter方法
}
(3)自动配置类定义
核心配置类,控制 Bean 的创建条件和逻辑,保证按需装配、可覆盖。
java
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* 短信自动配置类
* SpringBoot 3.x 推荐使用@AutoConfiguration替代@Configuration
*/
@AutoConfiguration // 替代3.x之前的@Configuration,标识自动配置类
@ConditionalOnClass(SmsTemplate.class) // 仅当类路径下存在SmsTemplate时才生效
@EnableConfigurationProperties(SmsProperties.class) // 启用配置项绑定,让SmsProperties生效
@ConditionalOnProperty(prefix = "sms", name = "enabled", matchIfMissing = true) // 仅当sms.enabled为true时生效,默认开启
public class SmsAutoConfiguration {
/**
* 注册SmsTemplate Bean
* @param props 注入短信配置项(Spring自动绑定)
* @return 阿里云短信模板实例
*/
@Bean // 向Spring容器注册Bean
@ConditionalOnMissingBean // 仅当容器中不存在SmsTemplate类型的Bean时才创建,允许用户自定义覆盖
public SmsTemplate smsTemplate(SmsProperties props) {
return new AliyunSmsTemplate(props);
}
}
(4)SPI 注册配置
让 SpringBoot 能扫描到自动配置类,3.x 版本需创建以下文件:
java
文件路径:src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件内容(配置自动配置类的全类名):
java
com.example.sms.boot.SmsAutoConfiguration
(5)配置元数据(可选)
辅助 IDE 实现配置项的自动提示,提升用户体验,创建以下文件:
文件路径:src/main/resources/META-INF/additional-spring-configuration-metadata.json
文件内容:
java
{
"properties": [
{
"name": "sms.enabled",
"type": "java.lang.Boolean",
"defaultValue": true,
"description": "短信服务总开关,默认开启。"
},
{
"name": "sms.access-key",
"type": "java.lang.String",
"description": "云厂商短信服务的AccessKey,必填。"
},
{
"name": "sms.secret-key",
"type": "java.lang.String",
"description": "云厂商短信服务的SecretKey,必填。"
},
{
"name": "sms.region",
"type": "java.lang.String",
"description": "云厂商短信服务的地域编码(如阿里云cn-hangzhou)。"
}
]
}
可借助 spring-boot-configuration-processor 依赖或 spring-boot-properties-maven-plugin 插件自动生成该文件,减少手动编写成本。
03.2 starter 模块开发
该模块为"空壳"模块,仅聚合依赖,简化用户引入操作。
Maven 依赖配置示例:
java
<dependencies>
<!-- 聚合autoconfigure模块,核心逻辑依赖 -->
<dependency>
<groupId>com.example.sms</groupId>
<artifactId>sms-spring-boot-autoconfigure</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 阿里云短信SDK,无需用户单独引入 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.24</version>
</dependency>
</dependencies>
03.3 Starter 使用示例
用户只需两步即可使用开发好的短信 Starter。
(1)引入 Starter 依赖
在项目的 pom.xml 中引入:
java
<dependency>
<groupId>com.example.sms</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
(2)配置短信参数
在 application.yml/application.properties 中配置:
java
sms:
access-key: your-aliyun-access-key # 替换为实际AccessKey
secret-key: your-aliyun-secret-key # 替换为实际SecretKey
region: cn-hangzhou # 替换为实际地域
# enabled: true # 默认开启,可省略
(3)注入使用
在业务代码中注入 SmsTemplate 即可使用:
java
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* 注册控制器示例
* 演示短信验证码发送功能
*/
@RestController
public class RegisterController {
// 注入Spring容器中的SmsTemplate Bean(自动配置类创建)
@Resource
private SmsTemplate smsTemplate;
/**
* 发送注册验证码
* @param mobile 手机号
* @return 操作结果
*/
@PostMapping("/send/register/code")
public String sendRegisterCode(@RequestParam String mobile) {
// 1. 生成6位随机验证码
String code = String.valueOf((int)((Math.random()*9+1)*100000));
// 2. 构建短信模板参数
Map<String, String> params = new HashMap<>();
params.put("code", code);
params.put("expireTime", "5"); // 有效期5分钟
// 3. 调用短信模板发送短信
SendResult result = smsTemplate.send(mobile, "XX平台", "SMS_123456789", params);
// 4. 处理发送结果
if (result.isSuccess()) {
return "验证码发送成功,请注意查收";
} else {
return "验证码发送失败:" + result.getMsg();
}
}
}
04 进阶:@Enable 注解的使用
除了通过 SPI 实现自动装配,还可以通过 @EnableXXX 注解手动控制 Starter 功能的开启/关闭,适用于高级能力的显式开关。
以短信 Starter 为例,实现 @EnableSms 注解,支持手动开启/关闭指标监控(metrics)能力。
04.1 定义 @EnableSms 注解
java
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* 开启短信功能注解
* 可手动控制是否开启短信功能及扩展能力(如metrics)
*/
@Target(ElementType.TYPE) // 注解作用于类/接口
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
@Documented // 生成文档时包含该注解
@Import(SmsConfigurationSelector.class) // 导入配置选择器,动态加载配置类
public @interface EnableSms {
/**
* 是否开启短信发送指标监控(如发送成功率、耗时等)
* @return 默认开启
*/
boolean metrics() default true;
}
04.2 实现配置选择器
通过 ImportSelector 动态选择需要加载的配置类:
java
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.MultiValueMap;
import org.springframework.core.type.AnnotationMetadata;
import java.util.ArrayList;
import java.util.List;
/**
* 短信配置选择器
* 根据@EnableSms注解的属性,动态加载对应的配置类
*/
public class SmsConfigurationSelector implements ImportSelector {
/**
* 选择需要导入的配置类全类名
* @param annotationMetadata 注解元数据(包含@EnableSms的属性)
* @return 配置类全类名数组
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 1. 获取@EnableSms注解的所有属性
MultiValueMap<String, Object> attrs = annotationMetadata.getAllAnnotationAttributes(EnableSms.class.getName());
// 2. 获取metrics属性值(默认true)
boolean metrics = attrs != null && (boolean) attrs.getFirst("metrics");
// 3. 构建需要导入的配置类列表
List<String> configClasses = new ArrayList<>();
// 核心短信自动配置类必加载
configClasses.add("com.example.sms.core.SmsAutoConfiguration");
// 如果开启metrics,加载指标监控配置类
if (metrics) {
configClasses.add("com.example.sms.actuate.SmsMetricsAutoConfiguration");
}
// 4. 转换为数组返回
return configClasses.toArray(new String[0]);
}
}
04.3 使用 @EnableSms 注解
在 SpringBoot 启动类上添加注解,显式控制功能:
java
import com.example.sms.annotation.EnableSms;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 应用启动类
* 通过@EnableSms手动关闭metrics能力
*/
@EnableSms(metrics = false) // 开启短信功能,关闭指标监控
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
05 Starter 最佳实践总结
- 基础功能:通过 SPI 机制实现自动装配,配置项通过 yaml/properties 注入,降低用户使用成本。
- 高级能力:配合 @EnableXXX 注解实现显式开关,让用户可按需开启扩展功能(如监控、日志等)。
- 兼容性:同时兼容 SpringBoot 2.x 和 3.x 的 SPI 注册方式,提升 Starter 适用范围。
- 可扩展:核心接口抽象化(如 SmsTemplate),方便扩展不同厂商的实现(阿里云、腾讯云等)。
- 易用性:提供配置元数据,辅助 IDE 自动提示,完善注释文档,降低用户接入门槛。