1.starter背景简介及作用
(1)什么是starter
(2)自定义starter的背景
- 大家应该都用过不少Starter,中间件很多,但也存在很多中间件缺少Starter或者不兼容
- 比如Spring Boot 3.x 版本更新,部分Starter就还没来得及更新,则使用不了
- 实际企业里面技术组长或架构师也会根据项目需求
- 封装自己的项目组的Starter,达到更快开发的项目,且可以统一规范,简化配置
(3)自定义Starter封装规范
- 官方的Starter包规范:spring-boot-starter-xxx
- 自定义Starter包规范:xxx-spring-boot-starter
spring-boot-starter
spring-boot-starter-data-jpa
spring-boot-starter-data-redis
spring-boot-starter-data-mongodb
spring-boot-starter-jdbc
mybatis-spring-boot-starter
mybatis-plus-boot-starter
(4)新版Spring Boot3.X和旧版SpringBoot2.7之前自定义Starter区别
-
SpringBoot2.7之前
- META-INF/spring.factories文件里添加
org.springframework.boot.autoconfigure.EnableAutoConfiguration=XXAutoConfiguration
- 关于springboot2.7之前自定义starter我会用另外一篇文章来展示。这里后续会更新哦!
- META-INF/spring.factories文件里添加
-
SpringBoot2.7推出新的自动配置
- 在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
- 文件里添加配置类名称,每行包含一个配置类全限定名
- 兼容META-INF/spring.factories方式
-
SpringBoot3.x 移除spring.factories
- 移除META-INF/spring.factories方式
- 只支持META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 增加自动配置
2.自定义starter的步骤
-
创建项目 xx-spring-boot-starter
-
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.0.2</version>
</dependency>
- 创建配置类
- 创建XXAutoConfiguration类
- 增加Condition条件注解
- 配置AutoConfiguration.imports自动配置类
3.自定义starter案例实战
(1)需求背景
- 现在公司所有的短信发送都集成到消息中心,为了简化各个平台的开发,自定义封装一个sms-starter提供给各个平台使用。
- 自定义一个发短信的sms-starter,starter对接各个三方的短信平台,阿里云、腾讯云、亚马逊云,开发者可以根据配置进行配置 短信的提供方,默认是 阿里云的提供方。
- 如果Spring容器没有对应的bean则创建,有的话则不创建。
(2)创建SpringBoot3.x项目 sms-spring-boot-starter,添加autoconfigure依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.0.2</version>
</dependency>
(3)创建配置类,通过 @ConfigurationProperties注解可以绑定application.yml配置文件
- 创建短信运营商的类型枚举类
public enum SmsTypeEnum {
//阿里云
ALI_CLOUD("ali"),
//腾讯云
TX_CLOUD("tx"),
//亚马逊云
YMX_CLOUD("ymx");
private String type;
SmsTypeEnum(String ymx) {}
}
@ConfigurationProperties(prefix = "sms.server.achieve")
public class SmsProperties {
/**
* 发送短信类型
*/
private String type;
public String getType() {
if(type == null || "".equals(type)){
type = SmsTypeEnum.ALI_YUN.name();
}
return type;
}
public void setType(String type) {
this.type = type;
}
}
(4)创建SmsService接口,封装三个云厂商的发送短信实现。
public interface SmsService {
String send(String fromPhone,String toPhone,String content);
}
/**
* 阿里云SMS实现
* @author lixiang
* @date 2023/5/16 09:30
*/
@Service("ali")
public class AliCloudSmsServiceImpl implements SmsService {
@Override
public String send(String fromPhone, String toPhone, String content) {
System.out.println("------------------当前SMS厂商为阿里云------------------");
System.out.println("----"+fromPhone+" 向 "+toPhone +" 发送了一条短信。"+"----");
System.out.println("短信内容为:"+content);
System.out.println("----------------------------------------------------");
return "success";
}
}
/**
* 腾讯云SMS实现
* @author lixiang
* @date 2023/5/16 09:44
*/
@Service("tx")
public class TxCloudSmsServiceImpl implements SmsService {
@Override
public String send(String fromPhone, String toPhone, String content) {
System.out.println("------------------当前SMS厂商为腾讯云------------------");
System.out.println("----"+fromPhone+" 向 "+toPhone +" 发送了一条短信。"+"----");
System.out.println("短信内容为:"+content);
System.out.println("----------------------------------------------------");
return "success";
}
}
/**
* 亚马逊云SMS实现
* @author lixiang
* @date 2023/5/16 09:42
*/
@Service("ymx")
public class YmxCloudSmsServiceImpl implements SmsService {
@Override
public String send(String fromPhone, String toPhone, String content) {
System.out.println("------------------当前SMS厂商为亚马逊云------------------");
System.out.println("----"+fromPhone+" 向 "+toPhone +" 发送了一条短信。"+"----");
System.out.println("短信内容为:"+content);
System.out.println("----------------------------------------------------");
return "success";
}
}
(5)定义SmsTemplate用于统一提供服务
/**
* @author lixiang
* @date 2023/5/16 09:33
*/
public class SmsTemplate {
@Autowired
private SmsProperties smsProperties;
@Autowired
private ApplicationContext context;
public String send(String fromPhone,String toPhone,String content){
//获取云厂商的业务实现类
String type = smsProperties.getType();
SmsService smsService = (SmsService)context.getBean(type);
return smsService.send(fromPhone,toPhone,content);
}
}
(6)定义SmsAutoConfiguration类
/**
* @author lixiang
* @date 2023/5/16 09:27
*/
@AutoConfiguration
@ConditionalOnClass(SmsTemplate.class)
@EnableConfigurationProperties(value = SmsProperties.class)
public class SmsAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public SmsTemplate smsTemplate(){
return new SmsTemplate();
}
}
(7)创建imports配置文件,把需要自动装载的类配置上。
- @AutoConfiguration 是spring boot2.7新引入的,自动配置类必须放进下面的文件里才算自动配置类
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.lixiang.config.SmsAutoConfiguration
(8)mvn clean install 打入到本地仓库
4.验证自定义starter
(1)新建项目,注意一定要是springboot3.x版本以上的。
<dependency>
<groupId>com.lixiang</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
(2)创建测试代码
@RestController
@RequestMapping("/spring-test")
public class TestController {
@Autowired
private SmsTemplate smsTemplate;
@RequestMapping("/sms")
public String sms(){
String fromPhone = "15522834580";
String toPhone = "13820345839";
String content = "李祥,李祥,今晚王者峡谷 六点 五缺一,收到请回复,over!";
return smsTemplate.send(fromPhone,toPhone,content);
}
}
(3)当配置文件不进行配置时,默认走的是阿里云的厂商。
(4)当配置好云厂商时,就会走配置的云厂商
Ok,SpringBoot3.x,自定义starter已经完成啦,后续会更新springboot2.x自定义starter的步骤,因为目前来看,很多企业还在用springboot2.x的版本。