SpringBoot封裝starter完整代碼示例
starter 機制
SpringBoot 采用約定大于配置思想,starter 是此思想的落地載體
starter 是將功能依賴 + 默認(rèn)配置 + 自動裝配打包成一個 jar,項目只要引入此 jar 即可獲得完整能力,無需關(guān)心底層到底需要哪些庫、怎么配 Bean
starter 規(guī)范
命名
官方:
spring-boot-starter-*?,如spring-boot-starter-web第三方:
xxx-spring-boot-starter?,如mybatis-spring-boot-starter版本管理
統(tǒng)一繼承 spring-boot-dependencies BOM,避免傳遞版本沖突
模塊劃分
xxx-spring-boot-starter(空殼,只管理依賴) xxx-spring-boot-autoconfigure(自動配置代碼) xxx-spring-boot-starter-core(可選,純業(yè)務(wù) API)
通過合理拆分模塊,實現(xiàn)職責(zé)單一、可插拔
自動配置類
使用注解 @Configuration,@AutoConfiguration 從 3.x 起替代 @Configuration
條件注解
使用 @ConditionalOnClass、@ConditionalOnProperty、@ConditionalOnMissingBean 等,防止重復(fù)裝配、保證可覆蓋
配置元數(shù)據(jù)
提供 spring-configuration-metadata.json,輔助 IDE 對配置自動提示
SPI 注冊
配置文件:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(3.x 版本)
spring.factories(2.x 版本)
可同時提供兩個版本來提高兼容性
開發(fā)實踐
以企業(yè)中短信功能為場景,封裝 SMS starter
SMS starter 分為兩個模塊
- sms-spring-boot-autoconfigure:自動配置、核心功能
- sms-spring-boot-stater:依賴管理
autoconfigure 模塊
配置項類
@Data
@ConfigurationProperties(prefix = "sms")
public class SmsProperties {
// 開關(guān)
private boolean enabled;
private String accessKey;
private String secretKey;
private String region;
}
核心功能接口與實現(xiàn)
// SMS 功能模板類
public interface SmsTemplate {
SendResult send(String mobile, String sign, String template, Map<String,String> params);
}
// 阿里云 SMS 功能實現(xiàn)
public class AliyunSmsTemplate implements SmsTemplate {
// implement...
}
自動配置類
@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
創(chuàng)建文件 src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
配置自動配置類全類名
com.example.sms.boot.SmsAutoConfiguration
配置元數(shù)據(jù)(可選)
創(chuàng)建文件 src/main/resources/META-INF/additional-spring-configuration-metadata.json
{
"properties": [
{
"name": "sms.enabled",
"type": "java.lang.Boolean",
"defaultValue": true,
"description": "是否開啟短信服務(wù)."
},
{
"name": "sms.access-key",
"type": "java.lang.String",
"description": "云廠商 AccessKey."
}
]
}
可以配合 spring-boot-configuration-processor? 或者 spring-boot-properties-maven-plugin 來自動生成此文件
starter 模塊
<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
<dependency>
<groupId>com.example.sms</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
yaml 配置
sms: access-key: xxxxx secret-key: xxxxx region: cn-hangzhou
注入使用
@RestController
class RegisterController {
// 注入 smsTemplate
@Resource
private SmsTemplate smsTemplate;
@PostMapping("/code")
public String sendCode(@RequestParam String mobile) {
// 使用 smsTemplate
// smsTemplate.send(...);
return "ok";
}
}
@Enable 注解
在 starter 開發(fā)中一個很重要的步驟是注冊 SPI,這是 SpringBoot 能自動掃描到 Configuration 從而進(jìn)行自動配置的原因
除了 SPI 注冊的方式,往往還能看到許多應(yīng)用提供了 @EnableXXX 注解,用于手動指定是否開啟功能特性
以 SMS starter 為例,編寫一個 @EnableSMS 注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(SmsConfigurationSelector.class)
public @interface EnableSms {
/**
* 是否開啟 metrics
*/
boolean metrics() default true;
}
原理是利用 @Import 把指定配置類直接送進(jìn)容器,常見三種模式:
@Import(XXX.class) → 普通配置類 @Import(Selector.class) → ImportSelector 可動態(tài)返回字符串?dāng)?shù)組 @Import(Registrar.class) → ImportBeanDefinitionRegistrar 可手動注冊 BeanDefinition
實現(xiàn) SmsConfigurationSelector
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]);
}
}
使用方式
@EnableSms(metrics = false)
@SpringBootApplication
public class DemoApplication {
// ...
}
starter 最佳實踐:
默認(rèn)功能使用 SPI 實現(xiàn)自動裝配,使用 yaml 實現(xiàn)配置項注入;高級能力配合 @EnableXXX 注解,方便顯式開關(guān)
總結(jié)
到此這篇關(guān)于SpringBoot封裝starter的文章就介紹到這了,更多相關(guān)SpringBoot封裝starter內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot中使用ConstraintValidatorContext驗證兩個字段內(nèi)容相同
開發(fā)修改密碼功能時,通過ConstraintValidator校驗新密碼和確認(rèn)新密碼的一致性,首先定義Matches注解和DTO對象,然后創(chuàng)建MatchesValidator類實現(xiàn)驗證邏輯,對springboot驗證字段內(nèi)容相同問題感興趣的朋友一起看看吧2024-10-10
詳解分別用Kotlin和java寫RecyclerView的示例
本篇文章主要介紹了詳解分別用Kotlin和java寫RecyclerView的示例,詳解分別用Kotlin和java寫RecyclerView的示例2017-12-12
解決MyBatis中為類配置別名,列名與屬性名不對應(yīng)的問題
這篇文章主要介紹了解決MyBatis中為類配置別名,列名與屬性名不對應(yīng)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
java實現(xiàn)文件變化監(jiān)控的方法(推薦)
下面小編就為大家?guī)硪黄猨ava實現(xiàn)文件變化監(jiān)控的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08
IntelliJ IDEA中查看當(dāng)前類的所有繼承關(guān)系圖
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中查看當(dāng)前類的所有繼承關(guān)系圖,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10
idea使用帶provide修飾依賴導(dǎo)致ClassNotFound
程序打包到Linux上運行時,若Linux上也有這些依賴,為了在Linux上運行時避免依賴沖突,可以使用provide修飾,本文主要介紹了idea使用帶provide修飾依賴導(dǎo)致ClassNotFound,下面就來介紹一下解決方法,感興趣的可以了解一下2024-01-01

