自定义 SpringBoot starter

本贴最后更新于 691 天前,其中的信息可能已经事过景迁

自定义 SpringBoot starter

1、了解 SpringBoot starter

SpringBoot 中的 starter 是一种非常重要的机制(自动化配置),能够抛弃以前繁杂的配置,将其统一集成进 starter,应用者只需要在 maven 中引入 starter 依赖,SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置。

starter 让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot 会自动通过 classpath 路径下的类发现需要的 Bean,并注册进 IOC 容器。SpringBoot 提供了针对日常企业应用研发各种场景的 spring-boot-starter 依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。

2、创建 Starter 的优点

  • 包含了许多我们需要的依赖项,以使项目快速启动和运行,并且具有一致的、被支持的一组管理传递依赖项
  • 不再需要担心依赖关系,它们将由 Spring Boot Starters 自动管理
  • 封装特定的应用程序 Starter,只需要通过简单的依赖引用即可,与实际业务代码解耦合

3、常用的 Starter

Spring 中已经提供了很多 Starter 给我们使用,常用的包括以下:

  • spring-boot-starter-data-elasticsearch:快速集成 Elasticsearch 的 Starter
  • spring-boot-starter-data-jpa:快速集成数据库的 Starter
  • spring-boot-starter-data-redis:快速集成 Redis 的 Starter
  • spring-boot-starter-aop:快速集成 AOP 切面编程的 Starter
  • spring-boot-starter-log4j2:快速集成 log4j2 的 Starter
  • spring-boot-starter-mail:快速集成邮件功能的 Starter
  • spring-boot-starter-quartz:定时任务的 Starter

Spring 还提供了很多 Starter 给我们使用,使用这些约定好的 Starter,可以更方便的集成第三方组件并使用 Starter 中提供的通用操作方法进行操作,不需要再很麻烦的通过一个个依赖去导入再配置来实现组件集成。

4、自定义 SpringBoot Starter

4.1 开发流程

  1. 创建 Start 项目
  2. 定义 Starter 需要的配置类(Properties)
  3. 编写 Starter 项目的业务功能
  4. 编写自动配置类
  5. 编写 spring.factories 文件来加载自动配置类
  6. 打包安装 Starter 依赖
  7. 其他项目引用 starter 并使用

4.2 案例一:自定义实现通用短信发送功能的 starter

1、创建 sms-spring-boot-starter 项目(使用 IDEA 创建)
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.10</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.apache.mf</groupId>
    <artifactId>sms-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sms-spring-boot-starter</name>
    <description>sms-spring-boot-starter</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2、定义 Starter 需要的配置类:SmsProperties
package org.apache.mf.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.io.Serializable;

/**
 * @Author: kyrie  @date: 2023/1/28 16:40
 * @Description:
 * @Package: org.apache.mf.config
 */
@ConfigurationProperties("global.sms")
public class SmsProperties implements Serializable {
    private static final long serialVersionUID = -3014361972477357324L;

    /**
     * 访问ID
     */
    private String accessKeyId;
    /**
     * 访问凭证
     */
    private String accessKeySecret;

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }
}

3、编写 Starter 项目的业务功能:发送短信
  • 接口:ISmsService
package org.apache.mf.service;

/**
 * @Author: kyrie  @date: 2023/1/28 16:44
 * @Description:
 * @Package: org.apache.mf.service
 */
public interface ISmsService {

    /**
     * 发送短信
     * @param phone           手机号
     * @param areaCode        手机区号
     * @param smsTemplateCode 短信模版code
     * @param data            发送数据
     */
    void send(String phone, String areaCode, String smsTemplateCode, String data);
}

  • 实现类:SmsServiceImpl
package org.apache.mf.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.mf.service.ISmsService;

/**
 * @Author: kyrie  @date: 2023/1/28 16:47
 * @Description:
 * @Package: org.apache.mf.service.impl
 */
@Slf4j
public class SmsServiceImpl implements ISmsService {

    /**
     * 访问ID
     */
    private String accessKeyId;
    /**
     * 访问凭证
     */
    private String accessKeySecret;

    public SmsServiceImpl(String accessKeyId, String accessKeySecret) {
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
    }

    /**
     * 发送短信
     *
     * @param phone           手机号
     * @param areaCode        手机区号
     * @param smsTemplateCode 短信模版code
     * @param data            发送数据
     */
    @Override
    public void send(String phone, String areaCode, String smsTemplateCode, String data) {
        log.info("##### 短信发送鉴权信息:accessKeyId={}, accessKeySecret={}", accessKeyId, accessKeySecret);
        log.info("##### 短信发送: 接收手机号:{},接收手机区号:{},短信模版code:{},短信内容为:{}", phone, areaCode, smsTemplateCode, data);
        // todo 具体业务逻辑自行实现
    }
}

4、编写自动配置类:SmsAutoConfig
package org.apache.mf.config;

import org.apache.mf.service.impl.SmsServiceImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @Author: kyrie  @date: 2023/1/28 16:51
 * @Description: 配置加载类
 * @Package: org.apache.mf.config
 */
@Configuration
@EnableConfigurationProperties({SmsProperties.class})
public class SmsAutoConfig {
    @Resource
    private SmsProperties smsProperties;

    @Bean
    public SmsServiceImpl smsServiceImpl() {
        return new SmsServiceImpl(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret());
    }
}

5、编写 spring.factories 文件来加载自动配置类

在 resources 目录下创建 META-INF/spring.factories 文件,编写自动配置信息

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.apache.mf.config.SmsAutoConfig
6、打包安装 Starter 依赖

使用 IDEA Maven 工具 clean 和 install 将依赖安装到本地(有私服可以安装到私服)

7、其他项目引用 starter 并使用
<dependency>
    <groupId>org.apache.mf</groupId>
    <artifactId>sms-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
@Service
@Slf4j
@RefreshScope
public class OrderAppServiceImpl implements OrderAppService {

    @Value("${order.orderNo}")
    private String orderNo;
    @Resource
    private UserAppApiRemoteFacade userAppApiRemoteFacade;

    @Resource
    private ISmsService smsService;

    @Override
    public UserOrderResDTO getOrderNo() {
        log.info("读取配置中心数据为: {}", orderNo);
        UserInfoResDTO userInfoResDTO = userAppApiRemoteFacade.getUserName();
        return UserOrderResDTO.builder().orderNo(orderNo).userName(userInfoResDTO.getNickName()).headUrl(userInfoResDTO.getHeadUrl()).build();
    }

    @Override
    public String send(SmsSendDTO smsSendDTO) {
        smsService.send(smsSendDTO.getPhone(), smsSendDTO.getAreaCode(), smsSendDTO.getSmsTemplateCode(), smsSendDTO.getData());
        return "发送成功!";
    }
}

4.2 案例二:自定义实现 AOP 切面日志的 Starter

详细请参考源码:

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    943 引用 • 1460 回帖 • 3 关注
  • Starter
    1 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...