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我会用另外一篇文章来展示。这里后续会更新哦!

    【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP

  • 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依赖

【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP

        <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

【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP

com.lixiang.config.SmsAutoConfiguration

(8)mvn clean install 打入到本地仓库

【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP

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)当配置文件不进行配置时,默认走的是阿里云的厂商。

【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP

(4)当配置好云厂商时,就会走配置的云厂商

【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP
【案例实战】SpringBoot3.x自定义封装starter实战-LMLPHP

Ok,SpringBoot3.x,自定义starter已经完成啦,后续会更新springboot2.x自定义starter的步骤,因为目前来看,很多企业还在用springboot2.x的版本。

05-17 01:47