starter 机制
springboot 采用约定大于配置思想,starter 是此思想的落地载体
starter 是将功能依赖 + 默认配置 + 自动装配打包成一个 jar,项目只要引入此 jar 即可获得完整能力,无需关心底层到底需要哪些库、怎么配 bean
starter 规范
命名
官方:
spring-boot-starter-*,如spring-boot-starter-web第三方:
xxx-spring-boot-starter,如mybatis-spring-boot-starter版本管理
统一继承 spring-boot-dependencies bom,避免传递版本冲突
模块划分
xxx-spring-boot-starter(空壳,只管理依赖) xxx-spring-boot-autoconfigure(自动配置代码) xxx-spring-boot-starter-core(可选,纯业务 api)
通过合理拆分模块,实现职责单一、可插拔
自动配置类
使用注解 @configuration,@autoconfiguration 从 3.x 起替代 @configuration
条件注解
使用 @conditionalonclass、@conditionalonproperty、@conditionalonmissingbean 等,防止重复装配、保证可覆盖
配置元数据
提供 spring-configuration-metadata.json,辅助 ide 对配置自动提示
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 模块
配置项类
@data
@configurationproperties(prefix = "sms")
public class smsproperties {
// 开关
private boolean enabled;
private string accesskey;
private string secretkey;
private string region;
}
核心功能接口与实现
// sms 功能模板类
public interface smstemplate {
sendresult send(string mobile, string sign, string template, map<string,string> params);
}
// 阿里云 sms 功能实现
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
创建文件 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
{
"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 模块
<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 开发中一个很重要的步骤是注册 spi,这是 springboot 能自动扫描到 configuration 从而进行自动配置的原因
除了 spi 注册的方式,往往还能看到许多应用提供了 @enablexxx 注解,用于手动指定是否开启功能特性
以 sms starter 为例,编写一个 @enablesms 注解
@target(elementtype.type)
@retention(retentionpolicy.runtime)
@documented
@import(smsconfigurationselector.class)
public @interface enablesms {
/**
* 是否开启 metrics
*/
boolean metrics() default true;
}
原理是利用 @import 把指定配置类直接送进容器,常见三种模式:
@import(xxx.class) → 普通配置类 @import(selector.class) → importselector 可动态返回字符串数组 @import(registrar.class) → importbeandefinitionregistrar 可手动注册 beandefinition
实现 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 最佳实践:
默认功能使用 spi 实现自动装配,使用 yaml 实现配置项注入;高级能力配合 @enablexxx 注解,方便显式开关
总结
到此这篇关于springboot封装starter的文章就介绍到这了,更多相关springboot封装starter内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论