SpringBoot 封装 starter

starter 机制

SpringBoot 采用约定大于配置思想,starter 是此思想的落地载体

starter 是将功能依赖 + 默认配置 + 自动装配打包成一个 jar,项目只要引入此 jar 即可获得完整能力,无需关心底层到底需要哪些库、怎么配 Bean

starter 规范

  1. 命名

    官方:spring-boot-starter-*​,如 spring-boot-starter-web

    第三方:xxx-spring-boot-starter​,如 mybatis-spring-boot-starter

  2. 版本管理

    统一继承 spring-boot-dependencies BOM,避免传递版本冲突

  3. 模块划分

    复制代码
    xxx-spring-boot-starter(空壳,只管理依赖)
    xxx-spring-boot-autoconfigure(自动配置代码)
    xxx-spring-boot-starter-core(可选,纯业务 API)

    通过合理拆分模块,实现职责单一、可插拔

  4. 自动配置类

    使用注解 @Configuration,@AutoConfiguration 从 3.x 起替代 @Configuration

  5. 条件注解

    使用 @ConditionalOnClass、@ConditionalOnProperty、@ConditionalOnMissingBean 等,防止重复装配、保证可覆盖

  6. 配置元数据

    提供 spring-configuration-metadata.json,辅助 IDE 对配置自动提示

  7. SPI 注册

    配置文件:

    • META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(3.x 版本)
    • spring.factories(2.x 版本)

    可同时提供两个版本来提高兼容性

开发实践

以企业中短信功能为场景,封装 SMS starter

SMS starter 分为两个模块

  • sms-spring-boot-autoconfigure:自动配置、核心功能
  • sms-spring-boot-stater:依赖管理

autoconfigure 模块

配置项类

typescript 复制代码
@Data
@ConfigurationProperties(prefix = "sms")
public class SmsProperties {
    // 开关
    private boolean enabled;
    private String accessKey;
    private String secretKey;
    private String region;
}

核心功能接口与实现

typescript 复制代码
// SMS 功能模板类
public interface SmsTemplate {
    SendResult send(String mobile, String sign, String template, Map<String,String> params);
}
​
// 阿里云 SMS 功能实现
public class AliyunSmsTemplate implements SmsTemplate {
    // implement...
}

自动配置类

less 复制代码
@AutoConfiguration // 3.x 版本代替 @Configuration 
@ConditionalOnClass(SmsTemplate.class)
@EnableConfigurationProperties(SmsProperties.class)
@ConditionalOnProperty(prefix = "sms", name = "enabled", matchIfMissing = true)
public class SmsAutoConfiguration {
​
    @Bean
    @ConditionalOnMissingBean
    public SmsTemplate smsTemplate(SmsProperties props) {
        return new AliyunSmsTemplate(props);
    }
}

注册 SPI

创建文件 src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

配置自动配置类全类名

复制代码
com.example.sms.boot.SmsAutoConfiguration

配置元数据(可选)

创建文件 src/main/resources/META-INF/additional-spring-configuration-metadata.json

json 复制代码
{
  "properties": [
    {
      "name": "sms.enabled",
      "type": "java.lang.Boolean",
      "defaultValue": true,
      "description": "是否开启短信服务."
    },
    {
      "name": "sms.access-key",
      "type": "java.lang.String",
      "description": "云厂商 AccessKey."
    }
  ]
}

可以配合 spring-boot-configuration-processor​ 或者 spring-boot-properties-maven-plugin 来自动生成此文件

starter 模块

xml 复制代码
<dependencies>
    <!-- 把 autoconfigure 与必要 SDK 全部聚合 -->
    <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>

starter 的使用

引入 starter

xml 复制代码
<dependency>
    <groupId>com.example.sms</groupId>
    <artifactId>sms-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

yaml 配置

yaml 复制代码
sms:
  access-key: xxxxx
  secret-key: xxxxx
  region: cn-hangzhou

注入使用

less 复制代码
@RestController
class RegisterController {
	// 注入 smsTemplate
    @Resource
    private SmsTemplate smsTemplate;

    @PostMapping("/code")
    public String sendCode(@RequestParam String mobile) {
		// 使用 smsTemplate
        // smsTemplate.send(...);
        return "ok";
    }
}

@Enable 注解

在 starter 开发中一个很重要的步骤是注册 SPI,这是 SpringBoot 能自动扫描到 Configuration 从而进行自动配置的原因

除了 SPI 注册的方式,往往还能看到许多应用提供了 @EnableXXX 注解,用于手动指定是否开启功能特性

以 SMS starter 为例,编写一个 @EnableSMS 注解

less 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(SmsConfigurationSelector.class)
public @interface EnableSms {
    /**
     * 是否开启 metrics
     */
    boolean metrics() default true;
}

原理是利用 @Import 把指定配置类直接送进容器,常见三种模式:

less 复制代码
@Import(XXX.class)       → 普通配置类
@Import(Selector.class)  → ImportSelector 可动态返回字符串数组
@Import(Registrar.class) → ImportBeanDefinitionRegistrar 可手动注册 BeanDefinition

实现 SmsConfigurationSelector

typescript 复制代码
public class SmsConfigurationSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata meta) {
        // 拿到注解属性
        MultiValueMap<String, Object> attrs =
                meta.getAllAnnotationAttributes(EnableSms.class.getName());
        boolean metrics = (boolean) attrs.getFirst("metrics");

        List<String> list = new ArrayList<>();
        list.add("com.example.sms.core.SmsAutoConfiguration");
		// 判断是否需要开启 metrics
        if (metrics) {
            list.add("com.example.sms.actuate.SmsMetricsAutoConfiguration");
        }
        return list.toArray(new String[0]);
    }
}

使用方式

less 复制代码
@EnableSms(metrics = false)
@SpringBootApplication
public class DemoApplication { 
	// ...
}

starter 最佳实践:

默认功能使用 SPI 实现自动装配,使用 yaml 实现配置项注入;高级能力配合 @EnableXXX 注解,方便显示开关

相关推荐
love530love6 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
星辰徐哥6 小时前
Spring Boot 微服务架构设计与实现
spring boot·后端·微服务
星辰徐哥6 小时前
Spring Boot 数据导入导出与报表生成
spring boot·后端·ui
明夜之约6 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee6 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐6 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
Jinkxs6 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
毕设源码_郑学姐6 小时前
计算机毕业设计springboot网络相册设计与实现 基于Spring Boot框架的在线相册管理系统开发与应用 Spring Boot驱动的网络影集设计与实践
spring boot·后端·课程设计
辣机小司6 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
一条小锦吕*6 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化