当前位置: 首页 > news >正文

打造专属Spring Boot Starter

如何为自己的库开发一个 Spring Boot Starter,并实现自动配置(Auto-Configuration)功能。

这属于 Spring Boot 高级开发技巧,通常用于:

  • 开发公司内部共享组件
  • 创建开源项目或商业 SDK
  • 封装通用能力(如短信、支付、日志增强等)

我将用 通俗语言 + 结构化方式 帮你彻底理解这一节的核心思想和实践步骤。


🌟 一、核心目标:什么是“自定义 Starter”?

✅ 一句话解释:

你想让你的 Java 库(比如叫 acme-sdk)能像 Spring Boot 的官方模块一样,只要引入一个依赖,就能自动生效、开箱即用

例如:

<dependency><groupId>com.acme</groupId><artifactId>acme-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>

引入后:

  • 自动配置好 AcmeClient
  • 支持 application.yml 中通过 acme.xxx 配置参数
  • 如果类路径有某个类才启用 → 智能判断

这就是所谓的 “Starter + Auto-Configuration” 机制


🔧 二、整体结构:一个典型的 Starter 包含什么?

一个完整的 Spring Boot Starter 通常由两个模块组成:

模块作用
acme-spring-boot-autoconfigure核心:包含自动配置逻辑、条件判断、@ConfigurationProperties
acme-spring-boot-starter外壳:只负责引入 autoconfigure 模块 + 实际 SDK 依赖

示例目录结构:

acme-spring-boot-starter/
├── pom.xml                          # 只引入 acme-autoconfigure 和 acme-sdk
└── src/└── main/└── resources/└── META-INF/└── maven/...acme-spring-boot-autoconfigure/
├── pom.xml                          # 依赖 spring-boot-autoconfigure, acme-sdk (optional)
├── src/
│   └── main/
│       └── java/
│           └── com/acme/autoconfigure/
│               ├── AcmeAutoConfiguration.java
│               └── AcmeProperties.java
│       └── resources/
│           └── META-INF/
│               ├── spring.factories
│               └── spring-configuration-metadata.json

📌 注意:这两个模块可以合并成一个,但如果功能复杂、可选特性多,建议拆开。


🛠️ 三、关键步骤详解

Step 1:写一个 Auto-Configuration 类

这是最核心的部分 —— 写一个带有 @Configuration 的类,告诉 Spring Boot “在什么条件下创建哪些 Bean”。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(AcmeClient.class)                    // 只有 AcmeClient 类存在时才加载
@ConditionalOnMissingBean                             // 用户没自己定义 AcmeClient 才创建
@EnableConfigurationProperties(AcmeProperties.class)   // 启用配置绑定
public class AcmeAutoConfiguration {@Beanpublic AcmeClient acmeClient(AcmeProperties properties) {return new AcmeClient(properties.getHost(), properties.getPort());}
}

✅ 这个类会在满足条件时自动注册 AcmeClient 到 Spring 容器。


Step 2:定义配置属性(支持 application.yml)

为了让用户可以通过 application.yml 配置你的组件,你需要定义 @ConfigurationProperties

@ConfigurationProperties("acme")
public class AcmeProperties {/*** Whether to check the location of acme resources.*/private boolean checkLocation = true;/*** Timeout for establishing a connection to the acme server.*/private Duration loginTimeout = Duration.ofSeconds(3);// getters & setters...
}

这样用户就可以写:

acme:host: api.acme.comport: 8080login-timeout: 5scheck-location: true

💡 IDE 还会提示补全(因为生成了元数据文件)!


Step 3:注册 Auto-Configuration(关键!)

Spring Boot 不会自动发现你的配置类,必须通过 META-INF/spring.factories 文件显式声明。

文件路径:
src/main/resources/META-INF/spring.factories
内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.acme.autoconfigure.AcmeAutoConfiguration,\
com.acme.autoconfigure.AcmeWebAutoConfiguration

⚠️ 注意事项:

  • 必须是这个 key:EnableAutoConfiguration
  • 多个类用 \ 换行连接
  • 该类不能被 @ComponentScan 扫到(避免重复加载)

Step 4:添加条件注解(Condition Annotations)

为了让自动配置更智能,你可以使用各种 @ConditionalOnXXX 来控制是否生效。

注解用途
@ConditionalOnClass(Xxx.class)当类路径中有 Xxx 类才启用
@ConditionalOnMissingBean当容器中没有该类型 Bean 才创建
@ConditionalOnProperty(name="acme.enabled", havingValue="true")当配置项开启时才启用
@ConditionalOnResource("classpath:acme-config.xml")存在某个资源文件才启用
@ConditionalOnWebApplication只在 Web 应用中启用
@ConditionalOnExpression("${flag} == true")SpEL 表达式控制

🎯 组合使用这些注解,可以让你的 starter 更加健壮、灵活。


Step 5:优化启动性能(推荐)

Spring Boot 提供了一个注解处理器,可以在编译期收集所有条件信息,加快启动速度。

添加依赖(在 autoconfigure 模块中):
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure-processor</artifactId><optional>true</optional>
</dependency>

它会在编译后生成 META-INF/spring-autoconfigure-metadata.properties,帮助 Spring Boot 提前过滤不匹配的配置类。

📌 注意:如果你只是在应用内写配置类(不是打包发布),不要把这个 jar 打进 fat jar。

Maven 排除方式:

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure-processor</artifactId></exclude></excludes></configuration>
</plugin>

Step 6:命名规范(重要!)

❌ 错误命名:
  • spring-boot-starter-acme (官方保留)
  • mycompany-acme-starter (缺少命名空间)
✅ 正确命名:
  • acme-spring-boot-starter
  • acme-spring-boot-autoconfigure

规则总结:

  1. 不要以 spring-boot 开头
  2. 使用你自己的命名空间(如 acme
  3. starter 模块命名为 xxx-spring-boot-starter
  4. autoconfigure 模块命名为 xxx-spring-boot-autoconfigure

Step 7:编写测试(确保稳定性)

Spring Boot 提供了 ApplicationContextRunner 工具来测试自动配置行为。

示例测试代码:
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(AcmeAutoConfiguration.class));@Test
void defaultServiceIsCreated() {contextRunner.run(context -> {assertThat(context).hasSingleBean(AcmeClient.class);});
}@Test
void customUserServiceOverridesAutoConfig() {contextRunner.withUserConfiguration(UserConfig.class).run(context -> {assertThat(context).getBean("myAcmeClient").isSameAs(context.getBean(AcmeClient.class));});
}@Test
void whenPropertySet_thenUsesCustomHost() {contextRunner.withPropertyValues("acme.host=testhost").run(context -> {AcmeClient client = context.getBean(AcmeClient.class);assertThat(client.getHost()).isEqualTo("testhost");});
}@Test
void whenAcmeClientNotPresent_thenAutoConfigDisabled() {contextRunner.withClassLoader(new FilteredClassLoader(AcmeClient.class)).run(context -> {assertThat(context).doesNotHaveBean(AcmeClient.class);});
}// 测试类
static class UserConfig {@BeanAcmeClient myAcmeClient() {return new AcmeClient("custom-host", 9999);}
}

✅ 这些测试可以验证:

  • 自动配置是否正常工作
  • 用户自定义 Bean 是否能覆盖
  • 配置项是否生效
  • 缺少依赖时是否会自动禁用

🧪 四、高级技巧补充

1. 控制加载顺序

有时候你的配置需要在其他配置之后执行(比如依赖 DataSource)。

@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class AcmeJdbcAutoConfiguration { ... }

或者指定优先级:

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)

2. 支持 Reactive 或 Servlet 环境

@ConditionalOnWebApplication(type = Type.SERVLET)
public class AcmeServletAutoConfiguration { }@ConditionalOnWebApplication(type = Type.REACTIVE)
public class AcmeReactiveAutoConfiguration { }

3. 文档化配置项(IDE 友好)

确保每个字段都有 Javadoc,这样会自动生成 spring-configuration-metadata.json,让 IDE 显示提示。

/*** Comma-separated list of locations to scan for acme resources.*/
private List<String> locations = Arrays.asList("/default");/*** Enable debug mode for acme engine.*/
private boolean debug = false;

✅ 总结:开发自定义 Starter 的完整流程

步骤操作
1️⃣创建两个模块:xxx-spring-boot-autoconfigurexxx-spring-boot-starter
2️⃣在 autoconfigure 模块中编写 @Configuration 类,使用 @ConditionalOnXXX 控制条件
3️⃣定义 @ConfigurationProperties("xxx") 绑定配置项
4️⃣META-INF/spring.factories 中注册自动配置类
5️⃣添加 spring-boot-autoconfigure-processor 提升启动性能
6️⃣编写单元测试,使用 ApplicationContextRunner 验证各种场景
7️⃣发布到 Maven 私服或公共仓库
8️⃣用户只需引入 starter,即可开箱即用

💡 实际应用场景举例

假设你要封装一个 阿里云短信发送 SDK

  • 模块名:aliyun-sms-spring-boot-starter
  • autoconfigure 模块包含:
    • SmsClientAutoConfiguration
    • SmsProperties(accessKey, secret, signName…)
  • starter 模块引入:
    • autoconfigure
    • 阿里云 SMS SDK
    • commons-lang3 等常用工具

用户只需:

<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-sms-spring-boot-starter</artifactId>
</dependency>
aliyun:sms:access-key: xxxsecret: yyysign-name: 企鹅科技

然后注入 SmsClient 就能发短信了 ✅


🎯 最后提醒

建议说明
✅ 使用 @ConditionalOnMissingBean让用户能轻松覆盖默认行为
✅ 把第三方依赖设为 <optional>true</optional>避免强制引入不需要的库
✅ 不要用 @ComponentScan 扫描 autoconfigure 包防止重复加载
✅ 提供清晰的文档和示例帮助用户快速上手

如果你想,我可以为你生成一个 完整的自定义 Starter 示例项目模板(含 pom.xml、配置类、测试等),帮助你快速上手 😊

http://www.dtcms.com/a/511941.html

相关文章:

  • Elasticsearch面试精讲 Day 30:Elasticsearch面试真题解析与答题技巧
  • 单一key-value对象工具-org.apache.commons.lang3.tuple.Pair
  • h5游戏免费下载:3D小车车
  • 分布式事务详解
  • Flink重启策略有啥用
  • 怎样做好物流网站建设免费商业wordpress主题
  • 怎么把qq空间做成企业网站网站用ps下拉效果怎么做
  • 输电线路绝缘子污秽度在线监测装置工作原理及优势解析
  • MOSHELL (7) : 构建3G RNC端到端性能可观测性体系
  • UE5 使用Lyra地图加载插件完成简易Loading
  • 最好的家:干净、烟火与书香
  • 普集网站开发湛江有哪些网站建设公司
  • 青岛开发区做网站海外服务器ip免费
  • 华为OD-23届转行-C++面经
  • 做腰椎核磁证网站是 收 七php如何制作网页
  • tail-f
  • 卸载Python3.12.6报错0x80070643安装时发生严重错误
  • 『 数据库 』MySQL复习 - 内置函数详解
  • Linux中Expect脚本和Shell的脚本核心特点解析、以及比对分析和应用场景
  • 网站建设公司未来发展方向傻瓜式php网站开发
  • Redis缓存--Jedis
  • 三点式振荡器(Colpitts/Hartley)的相关问题
  • 西安淘宝网站建设公司ui设计需要学哪些课程
  • h5游戏免费下载:任意球大师
  • DL2421P1 24V DFN1006封装低电容ESD保护二极管0.3pF,80W,1.5A IPP@8/20uS VC53V
  • 【Threejs-sdk】使用 mogl.js 快速匹配烘焙.
  • 泸州市住房和城乡建设局网站企业信息查询系统官网上海
  • Web原生架构 vs 传统C/S架构:在数据库管理中的性能与安全差异
  • HTTPS 爬虫实战指南 从握手原理到反爬应对与流量抓包分析
  • 淘宝客网站开发服务商酒类营销网站