SpringBoot инкапсулирует свой собственный Starter

Spring Boot

1. Описание

Когда мы используем SpringBoot, мы часто вводим некоторые Starters, такие как spring-boot-starter-web, Официальный предоставляет нам почти все конфигурации по умолчанию, что снижает сложность использования фреймворка, поэтому мы используем xxx-starter Когда у вас есть Стартер, можно не заморачиваться писать какие-то нудные файлы конфигурации, даже если нужная конфигурация настроена в application.properties или application.yml, при реализации Стартера его можно переиспользовать в разных проектах, что очень удобно , Сегодня мы напишем свой Стартер на примере предыдущего СМС-бизнеса.

Вызов службы SMS Springboot:nuggets.capable/post/684490…

spring-boot-starter-xxx — это правило именования для официального Starter, а официальная рекомендация для правила именования для неофициального Starter — xxx-spring-boot-starter.

2. Создайте проект

Создайте проект SpringBoot и очистите файлы и папки в ресурсах.

Зависимости Maven следующие:

 <dependencies>
        <!--封装Starter核心依赖  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
        <!--非必需,该依赖作用是在使用IDEA编写配置文件有代码提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
        <!-- lombok 插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
            <optional>true</optional>
        </dependency>
        <!-- 因为要使用RestTemplate和转换Json,所以引入这两个依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.45</version>
        </dependency>
</dependencies>

Spring-boot-configuration-processor не нужен. Его функция заключается в создании spring-configuration-metadata.json при компиляции. Этот файл в основном используется IDEA. Чтобы настроить это свойство конфигурации, связанное с JAR, в application.yml, вы можете используйте Ctrl+ Щелкните имя свойства левой кнопкой мыши, и среда IDE перейдет к классу, в котором вы настраиваете это свойство.При написании application.yml появятся подсказки кода.

2. Напишите базовый класс проекта

Создайте класс передачи SendSMSDTO для передачи параметров

/**
 * SMSDTO参数类
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention
 */
@Data
public class SendSMSDTO {
    /**
     * 模板ID
     */
    private String templateid;
    /**
     * 参数
     */
    private String param;
    /**
     * 手机号
     */
    private String mobile;
    /**
     * 用户穿透ID,可以为空
     */
    private String uid;
}

Создайте класс конфигурации RestTemplateConfig для вызова интерфейса SMS.

/**
 * RestTemplateConfig配置
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention
 */
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate( ) {
        return new RestTemplate();
    }
}

Создайте класс перечисления интерфейса SMS для хранения адреса API интерфейса SMS.

/**
 * 短信请求API枚举
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention
 */
@Getter
public enum ENUM_SMSAPI_URL {
    SENDSMS("https://open.ucpaas.com/ol/sms/sendsms"),
    SENDBATCHSMS("https://open.ucpaas.com/ol/sms/sendsms_batch");
    private String url;
    ENUM_SMSAPI_URL(String url) {
        this.url = url;
    }
}

3. Напишите класс автоматической настройки Starter

Создайте класс свойств конфигурации SmsProperties, который в основном используется для чтения информации yml/properties.

/**
 * SMS配置属性类
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention 使用ConfigurationProperties注解可将配置文件(yml/properties)中指定前缀的配置转为bean
 */
@Data
@ConfigurationProperties(prefix = "sms-config")
public class SmsProperties {
    private String appid;
    private String accountSid;
    private String authToken;
}

Создать базовый класс обслуживания SMS

/**
 * 短信核心服务类
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention
 */
public class SmsService {

    @Autowired
    private RestTemplate restTemplate;
    private String appid;
    private String accountSid;
    private String authToken;

    /**
     * 初始化
     */
    public SmsService(SmsProperties smsProperties) {
       this.appid = smsProperties.getAppid();
       this.accountSid = smsProperties.getAccountSid();
       this.authToken = smsProperties.getAuthToken();
    }

    /**
     * 单独发送
     */
    public String sendSMS(SendSMSDTO sendSMSDTO){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("sid", accountSid);
        jsonObject.put("token", authToken);
        jsonObject.put("appid", appid);
        jsonObject.put("templateid", sendSMSDTO.getTemplateid());
        jsonObject.put("param", sendSMSDTO.getParam());
        jsonObject.put("mobile", sendSMSDTO.getMobile());
        if (sendSMSDTO.getUid()!=null){
            jsonObject.put("uid",sendSMSDTO.getUid());
        }else {
            jsonObject.put("uid","");
        }
        String json = JSONObject.toJSONString(jsonObject);
        //使用restTemplate进行访问远程Http服务
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> httpEntity = new HttpEntity<String>(json, headers);
        String result = restTemplate.postForObject(ENUM_SMSAPI_URL.SENDSMS.getUrl(), httpEntity, String.class);
        return result;
    }

    /**
     * 群体发送
     */
    public String sendBatchSMS(SendSMSDTO sendSMSDTO){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("sid", accountSid);
        jsonObject.put("token", authToken);
        jsonObject.put("appid", appid);
        jsonObject.put("templateid", sendSMSDTO.getTemplateid());
        jsonObject.put("param", sendSMSDTO.getParam());
        jsonObject.put("mobile", sendSMSDTO.getMobile());
        if (sendSMSDTO.getUid()!=null){
            jsonObject.put("uid",sendSMSDTO.getUid());
        }else {
            jsonObject.put("uid","");
        }
        String json = JSONObject.toJSONString(jsonObject);
        //使用restTemplate进行访问远程Http服务
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> httpEntity = new HttpEntity<String>(json, headers);
        String result = restTemplate.postForObject(ENUM_SMSAPI_URL.SENDBATCHSMS.getUrl(), httpEntity, String.class);
        return result;
    }
}

Создайте класс автоматической конфигурации SmsAutoConfiguration, который в основном используется для создания основных экземпляров бизнес-класса.

/**
 * 短信自动配置类
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention
 */
@Configuration  
@EnableConfigurationProperties(SmsProperties.class)//使@ConfigurationProperties注解生效
public class SmsAutoConfiguration {
    @Bean
    public SmsService getBean(SmsProperties smsProperties){
        SmsService smsService = new SmsService(smsProperties);
        return smsService;
    }
}

4. Создайте файл spring.factories

spring.factories Этот файл используется для определения классов, которые необходимо настроить автоматически.При запуске SpringBoot будет создан экземпляр объекта, файл конфигурации будет загружен путем загрузки класса SpringFactoriesLoader, а классы конфигурации в файле будут загружены в пружинный контейнер.

Создайте новую папку META-INF в src/main/resources и создайте новый файл spring.factories в папке META-INF.Содержимое конфигурации выглядит следующим образом:

 org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.sms.starter.config.SmsAutoConfiguration

5. Упаковка и тестирование

Используйте подключаемый модуль Maven для упаковки и установки проекта на локальное хранилище.

Создайте новый тестовый проект, введите наш собственный Starter и зависимости Maven:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 添加我们自己的starter-->
        <dependency>
            <groupId>com.sms.starter</groupId>
            <artifactId>sms-spring-boot-starter</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
</dependencies>

Настройте application.yml тестового проекта

sms-config:
  account-sid:  //这里填写平台获取的ID和KEY
  auth-token:   //这里填写平台获取的ID和KEY
  appid:        //这里填写平台获取的ID和KEY

Параметры Заполните номер своего мобильного телефона, шаблон, на который подана заявка, и соответствующие параметры

/**
 * 测试短信DEMO
 * @Author Sans
 * @CreateTime 2019/4/20 
 * @attention
 */
@RestController
@RequestMapping("/sms")
public class TestController {
    @Autowired
    private SmsService smsService;
    /**
     * 短信测试
     * @Attention
     * @Author: Sans
     * @CreateTime: 2019/4/20 
     */
    @RequestMapping(value = "/sendsmsTest",method = RequestMethod.GET)
    public String sendsmsTest(){
        //创建传输类设置参数
        SendSMSDTO sendSMSDTO  = new SendSMSDTO();
        sendSMSDTO.setMobile("");     //手机号
        sendSMSDTO.setTemplateid(""); //模板
        sendSMSDTO.setParam("");      //参数
        return smsService.sendSMS(sendSMSDTO);
    }
}

6. Последующие добавки

При представлении своего собственного упакованного Starter некоторые люди сообщают, что класс bean-компонента **** не найден, потому что областью действия пакета сканирования @SpringBootApplication является пакет и подпакет того же уровня, где находится класс запуска, но не включить сторонние банки Пакет, Если нам нужно сканировать Jar, добавленный зависимостями maven, нам нужно использовать аннотацию @ComponentScan для сканирования пакета отдельно. Для этой ситуации есть два решения:

Первый: имя родительского пакета в инкапсулированном вами проекте Starter совпадает с именем родительского пакета тестового проекта.Например, имена пакетов этих двух проектов называются com.sans, поэтому @ComponentScan аннотацию можно опустить.Очевидно, что так и делается.Это имеет ограничения и не рекомендуется.

Второе: вы можете использовать только аннотацию @ComponentScan для сканирования сторонних пакетов, но здесь необходимо отметить, что аннотация @SpringBootApplication эквивалентна свойству по умолчанию с использованием @Configuration+@EnableAutoConfiguration+@ComponentScan, если аннотации @SpringBootApplication и @ComponentScan существуют одновременно, то @SpringBootApplication Диапазон сканирования @ComponentScan в аннотации будет перезаписан, поэтому, если вы используете только @ComponentScan, вы должны настроить все области пакета, которые проект должен сканировать в аннотации, что то есть путь к пакету проекта + путь к пакету зависимостей.

/**
 * @ComponentScan注解扫描多个包下示例
 */
@ComponentScan({"com.test","sms.test"})

Исходный код проекта:git ee.com/Maroon Lotte/ это…

Нелегко публиковать сообщения поздно ночью, я надеюсь, что большие ребята могут высказать ценное мнение.