首页
/ SMS4J项目架构解析

SMS4J项目架构解析

2026-02-04 05:07:19作者:凌朦慧Richard

SMS4J是一个高度模块化的信息发送框架,通过核心模块、服务提供商模块、通信模块、配置模块、插件模块和工厂模块的协同工作,实现了对多种信息服务的灵活支持。其设计注重高内聚、低耦合,便于扩展和维护。

SMS4J的模块化设计

SMS4J 是一个高度模块化的信息发送框架,其设计旨在通过清晰的模块划分和灵活的扩展机制,支持多种信息服务提供商的集成。以下是对其模块化设计的详细解析:

1. 核心模块(Core)

核心模块是 SMS4J 的基础,提供了信息发送的核心接口和抽象类。这些接口定义了通用的信息发送行为,如发送单条信息、批量发送信息等。核心模块的主要组件包括:

  • SmsBlend:定义了信息发送的核心接口,所有信息服务提供商必须实现此接口。
  • AbstractSmsBlend:提供了信息发送的默认实现,包括异步发送和延迟发送功能。
  • SmsResponse:封装了信息发送的响应结果,包括成功/失败状态和相关数据。
public interface SmsBlend {
    SmsResponse sendMessage(String phone, String message);
    SmsResponse sendMessage(String phone, LinkedHashMap<String, String> messages);
    SmsResponse sendMessage(String phone, String templateId, LinkedHashMap<String, String> messages);
    SmsResponse massTexting(List<String> phones, String message);
    SmsResponse massTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages);
}

2. 服务提供商模块(Provider)

服务提供商模块是 SMS4J 的扩展点,每个信息服务提供商(如阿里云、腾讯云、华为云等)通过实现 SmsBlend 接口,提供具体的信息发送逻辑。每个服务提供商模块包含以下组件:

  • XXXConfig:配置类,存储服务提供商的认证信息(如 appKeyIdappKeySecret)。
  • XXXFactory:工厂类,负责创建服务提供商的实例。
  • XXXSmsImpl:实现类,封装了与服务提供商 API 的交互逻辑。
classDiagram
    class SmsBlend {
        <<interface>>
        +sendMessage()
        +massTexting()
    }
    class AlibabaSmsImpl {
        +sendMessage()
        +massTexting()
    }
    class TencentSmsImpl {
        +sendMessage()
        +massTexting()
    }
    SmsBlend <|-- AlibabaSmsImpl
    SmsBlend <|-- TencentSmsImpl

3. 通信模块(Comm)

通信模块负责处理与信息服务提供商的 HTTP 通信,包括请求构造、签名生成和响应解析。主要组件包括:

  • SmsHttpUtils:封装了 HTTP 请求的发送逻辑。
  • SmsUtils:提供了一些通用的工具方法,如类加载检查。
  • SettingUtils:用于读取配置文件中的设置。
public class SmsHttpUtils {
    public static String post(String url, Map<String, String> headers, String body) {
        // HTTP 请求实现
    }
}

4. 配置模块(Config)

配置模块通过 YAML 或 Properties 文件加载信息发送的全局配置和服务提供商配置。核心组件包括:

  • SmsConfig:全局配置,如线程池大小、重试策略等。
  • XXXConfig:服务提供商的具体配置。
sms:
  corePoolSize: 10
  maxPoolSize: 30
  blends:
    alibaba:
      appKeyId: your-app-key
      appKeySecret: your-secret-key

5. 插件模块(Plugin)

插件模块为 SMS4J 提供了额外的功能扩展,如:

  • BlackListProcessor:黑名单过滤插件。
  • RestrictedProcessor:限流插件。
  • DelayedTime:延迟任务调度插件。
flowchart TD
    A[信息发送请求] --> B{是否在黑名单中?}
    B -->|是| C[拒绝发送]
    B -->|否| D[继续处理]

6. 工厂模块(Factory)

工厂模块通过 SmsFactoryProviderFactoryHolder 动态加载和管理服务提供商实例。核心功能包括:

  • SmsFactory:根据配置创建和获取服务提供商实例。
  • ProviderFactoryHolder:注册和管理服务提供商的工厂类。
public class SmsFactory {
    public static SmsBlend getSmsBlend(String configId) {
        // 根据配置 ID 获取服务提供商实例
    }
}

模块交互流程

以下是 SMS4J 模块间的典型交互流程:

sequenceDiagram
    participant User
    participant SmsFactory
    participant AlibabaSmsImpl
    participant SmsHttpUtils
    User->>SmsFactory: 获取阿里云实例
    SmsFactory->>AlibabaSmsImpl: 创建实例
    User->>AlibabaSmsImpl: 发送信息
    AlibabaSmsImpl->>SmsHttpUtils: 构造 HTTP 请求
    SmsHttpUtils->>AlibabaSmsImpl: 返回响应
    AlibabaSmsImpl->>User: 返回 SmsResponse

通过这种模块化设计,SMS4J 实现了高内聚、低耦合的架构,便于扩展和维护。开发者可以根据需求轻松集成新的信息服务提供商或扩展功能插件。

核心模块:sms4j-api、sms4j-core、sms4j-comm

SMS4J的核心模块由sms4j-apisms4j-coresms4j-comm组成,这三个模块共同构成了项目的核心功能架构。以下是对这三个模块的详细解析:

sms4j-api

sms4j-api模块定义了项目的核心接口和抽象类,为其他模块提供了统一的编程接口。其主要功能包括:

  1. 核心接口

    • SmsBlend:定义了信息发送的核心方法,如sendMessagesendMessageByTemplate
    • SmsProcessor:提供了信息发送前后的处理逻辑,支持自定义拦截器。
    • SmsDao:定义了数据访问接口,用于缓存信息发送记录。
  2. 工具类

    • SmsRespUtils:封装了信息响应的工具方法,如successerror
    • SmsHttpUtils:提供了HTTP请求的工具方法,支持JSON和表单数据的发送。
  3. 回调与配置

    • CallBack:定义了回调接口,用于异步处理信息发送结果。
    • SupplierConfig:定义了供应商配置接口,支持动态加载配置。
// 示例:使用SmsBlend发送信息
SmsBlend smsBlend = SmsFactory.getSmsBlend("aliyun");
smsBlend.sendMessage("18888888888", "您的验证码是123456");

sms4j-core

sms4j-core模块实现了sms4j-api中定义的核心功能,并提供了额外的扩展支持。其主要功能包括:

  1. 工厂类

    • SmsFactory:用于创建和管理信息发送实例,支持多供应商的动态切换。
    • SmsProxyFactory:提供了代理工厂,支持对信息发送过程的拦截和增强。
  2. 处理器

    • CoreMethodParamValidateProcessor:验证信息发送参数的有效性。
    • RestrictedProcessor:实现了信息发送的频率限制功能。
  3. 工具类

    • SmsUtils:提供了字符串处理和JSON转换的工具方法。
    • SmsDateUtils:封装了日期和时间的格式化工具。
classDiagram
    class SmsFactory {
        +getSmsBlend(String configId): SmsBlend
        +register(SmsBlend smsBlend, Integer weight): void
    }
    class SmsProxyFactory {
        +getProxySmsBlend(SmsBlend smsBlend): SmsBlend
    }
    SmsFactory --> SmsProxyFactory

sms4j-comm

sms4j-comm模块提供了通用的工具类和异常处理机制,为其他模块提供了基础支持。其主要功能包括:

  1. 异常处理

    • SmsBlendException:定义了信息发送过程中的异常类。
    • SmsSqlException:封装了数据库操作相关的异常。
  2. 工具类

    • SmsHttpUtils:提供了HTTP请求的工具方法,支持多种请求方式。
    • SettingUtils:用于读取配置文件中的设置。
  3. 任务调度

    • Task:定义了任务调度的基础接口。
    • DelayedTime:实现了延迟任务的调度功能。
flowchart TD
    A[发送信息请求] --> B{参数验证}
    B -->|通过| C[调用供应商接口]
    B -->|失败| D[返回错误响应]
    C --> E[处理响应结果]
    E --> F[返回成功响应]

模块协作

这三个模块通过以下方式协同工作:

  1. sms4j-api定义了统一的接口规范。
  2. sms4j-core实现了核心功能,并通过工厂模式管理实例。
  3. sms4j-comm提供了通用的工具和异常处理支持。
mindmap
  root((SMS4J核心模块))
    sms4j-api
      接口定义
      工具类
    sms4j-core
      工厂模式
      处理器
    sms4j-comm
      异常处理
      通用工具

## 插件化架构:支持多种信息服务商

SMS4J 的核心设计理念之一是插件化架构,通过这种架构,项目能够灵活支持多种信息服务商,而无需修改核心代码。这种设计不仅提高了扩展性,还使得开发者可以轻松集成新的信息服务商。

### 插件化架构的核心组件

1. **`SmsBlend` 接口**  
   所有信息服务商的实现类都必须实现 `SmsBlend` 接口。该接口定义了信息发送的基本方法,包括单条信息发送、批量发送、模板信息发送等。以下是接口的关键方法:

   ```java
   public interface SmsBlend {
       SmsResponse sendMessage(String phone, String message);
       SmsResponse sendMessage(String phone, LinkedHashMap<String, String> messages);
       SmsResponse sendMessage(String phone, String templateId, LinkedHashMap<String, String> messages);
       SmsResponse massTexting(List<String> phones, String message);
       SmsResponse massTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages);
   }
  1. AbstractSmsBlend 抽象类
    为减少重复代码,SMS4J 提供了 AbstractSmsBlend 抽象类,实现了 SmsBlend 接口的基础功能。开发者只需继承此类并实现特定服务商的逻辑即可。

    public abstract class AbstractSmsBlend<C extends SupplierConfig> implements SmsBlend {
        // 基础实现
    }
    
  2. SupplierConfig 配置类
    每个信息服务商都有独立的配置类,继承自 SupplierConfig。这些配置类包含了服务商所需的认证信息、请求地址等参数。

    public class AlibabaConfig extends SupplierConfig {
        private String appKeyId;
        private String appKeySecret;
        private String signature;
        // 其他配置项
    }
    
  3. ProviderFactory 工厂类
    每个服务商都有一个对应的工厂类,负责创建其实例。工厂类通过 ProviderFactoryHolder 注册到系统中。

    public class AlibabaFactory implements BaseProviderFactory<AlibabaSmsImpl, AlibabaConfig> {
        @Override
        public AlibabaSmsImpl createSms(AlibabaConfig config) {
            return new AlibabaSmsImpl(config);
        }
    }
    

如何扩展新的信息服务商

以下是为 SMS4J 添加新信息服务商的步骤:

  1. 创建配置类
    继承 SupplierConfig,定义服务商所需的配置参数。

    public class NewProviderConfig extends SupplierConfig {
        private String apiKey;
        private String apiSecret;
        // 其他配置项
    }
    
  2. 实现 SmsBlend 接口
    继承 AbstractSmsBlend,实现服务商特定的信息发送逻辑。

    public class NewProviderSmsImpl extends AbstractSmsBlend<NewProviderConfig> {
        @Override
        public SmsResponse sendMessage(String phone, String message) {
            // 实现发送逻辑
        }
    }
    
  3. 创建工厂类
    实现 BaseProviderFactory,用于创建服务商实例。

    public class NewProviderFactory implements BaseProviderFactory<NewProviderSmsImpl, NewProviderConfig> {
        @Override
        public NewProviderSmsImpl createSms(NewProviderConfig config) {
            return new NewProviderSmsImpl(config);
        }
    }
    
  4. 注册工厂类
    在项目启动时,通过 ProviderFactoryHolder 注册工厂类。

    ProviderFactoryHolder.registerFactory(new NewProviderFactory());
    

支持的信息服务商

SMS4J 目前支持以下信息服务商(部分):

服务商名称 配置类 实现类
阿里云信息 AlibabaConfig AlibabaSmsImpl
腾讯云信息 TencentConfig TencentSmsImpl
华为云信息 HuaweiConfig HuaweiSmsImpl
京东云信息 JdCloudConfig JdCloudSmsImpl
网易云信信息 NeteaseConfig NeteaseSmsImpl

示例:使用阿里云信息发送消息

以下是通过阿里云信息发送消息的代码示例:

// 配置阿里云信息
AlibabaConfig config = new AlibabaConfig();
config.setAppKeyId("your-app-key-id");
config.setAppKeySecret("your-app-key-secret");
config.setSignature("your-signature");

// 创建信息实例
AlibabaSmsImpl sms = new AlibabaSmsImpl(config);

// 发送信息
SmsResponse response = sms.sendMessage("18888888888", "您的验证码是123456");

架构优势

  1. 灵活性
    通过插件化设计,开发者可以轻松替换或新增信息服务商,而无需修改核心代码。

  2. 可维护性
    每个服务商的实现和配置独立,便于维护和升级。

  3. 扩展性
    支持快速集成新的信息服务商,满足业务需求的变化。

通过这种架构,SMS4J 实现了对多种信息服务商的无缝支持,为开发者提供了极大的便利。

Spring Boot集成与扩展

SMS4J 提供了与 Spring Boot 的无缝集成能力,通过 sms4j-spring-boot-starter 模块,开发者可以快速将信息功能集成到 Spring Boot 应用中。本节将详细介绍如何在 Spring Boot 中配置和使用 SMS4J,并探讨其扩展机制。

1. 快速集成

1.1 引入依赖

pom.xml 中添加以下依赖:

<dependency>
    <groupId>org.dromara.sms4j</groupId>
    <artifactId>sms4j-spring-boot-starter</artifactId>
    <version>3.3.5</version>
</dependency>

1.2 配置信息服务商

application.yml 中配置信息服务商信息,支持多厂商动态切换:

sms:
  config-type: yaml
  blends:
    aliyun:
      appKeyId: 您的appKey
      appKeySecret: 您的appKeySecret
      signature: 测试签名
      templateId: SMS_215125134
      templateName: code
      requestUrl: dysmsapi.aliyuncs.com
    huawei:
      appKey: 5N6fvXXXX920HaWhVXXXXXX7fYa
      app-secret: Wujt7EYzZTBXXXXXXEhSP6XXXX
      signature: 华为信息测试
      sender: 8823040504797
      template-id: acXXXXXXXXc274b2a8263479b954c1ab5
      url: https://XXXXX.cn-north-4.XXXXXXXX.com:443

1.3 使用示例

通过 SmsFactory 动态获取信息服务实例:

@RestController
@RequestMapping("/sms")
public class SmsController {

    @GetMapping("/send")
    public void sendSms() {
        // 发送阿里云信息
        SmsFactory.getSmsBlend("aliyun").sendMessage("18888888888", "123456");
        // 发送华为信息
        SmsFactory.getSmsBlend("huawei").sendMessage("16666666666", "000000");
    }
}

2. 扩展机制

SMS4J 提供了灵活的扩展机制,支持开发者自定义信息服务商或覆盖默认行为。

2.1 自定义信息服务商

实现 SmsBlend 接口并注册为 Spring Bean:

@Component
public class CustomSmsBlend implements SmsBlend {
    @Override
    public String getSupplier() {
        return "custom";
    }

    @Override
    public SmsResponse sendMessage(String phone, String message) {
        // 自定义发送逻辑
        return new SmsResponse();
    }
}

2.2 动态配置覆盖

通过 SmsSpringUtils 动态修改配置或替换 Bean:

@Autowired
private SmsSpringUtils smsSpringUtils;

public void updateConfig() {
    // 动态替换配置
    smsSpringUtils.replaceBean("aliyunConfig", new CustomAliyunConfig());
}

3. 高级配置

3.1 线程池配置

SMS4J 默认使用线程池处理异步信息任务,可通过以下配置调整:

sms:
  corePoolSize: 10
  maxPoolSize: 30
  queueCapacity:
登录后查看全文
热门项目推荐
相关项目推荐