基于Spring Boot的短信平台平滑切换设计方案

基于Spring Boot的短信平台平滑切换设计方案

案例背景

在电商系统中,短信服务是用户注册、登录验证、订单通知等环节的关键基础设施。由于业务需求或成本优化,企业可能需要在不同短信平台(如阿里云、腾讯云、云片等)之间进行切换。传统做法需要修改代码并重新部署,这会导致系统停机和服务中断。

本文将介绍如何通过Spring Boot的配置机制和设计模式实现短信平台的平滑切换,无需修改调用处的业务代码。

设计方案

1. 整体架构设计

采用"策略模式+工厂模式"结合Spring的依赖注入机制:

  • 定义统一的短信服务接口
  • 为每个短信平台实现具体策略
  • 通过配置决定激活哪个实现
  • 工厂类负责返回正确的短信服务实例

2. 核心实现代码

定义统一接口
public interface SmsService {/*** 发送短信* @param phone 手机号* @param content 短信内容* @return 发送结果*/SendResult send(String phone, String content);/*** 发送模板短信* @param phone 手机号* @param templateId 模板ID* @param params 模板参数* @return 发送结果*/SendResult sendWithTemplate(String phone, String templateId, Map<String, String> params);
}
实现不同平台策略(以阿里云为例)
@Slf4j
@Service
@ConditionalOnProperty(name = "sms.provider", havingValue = "aliyun")
public class AliyunSmsService implements SmsService {@Value("${sms.aliyun.access-key-id}")private String accessKeyId;@Value("${sms.aliyun.access-key-secret}")private String accessKeySecret;@Overridepublic SendResult send(String phone, String content) {// 阿里云短信发送实现log.info("使用阿里云短信平台发送短信至:{}", phone);// 实际调用阿里云SDKreturn new SendResult(true, "阿里云发送成功");}@Overridepublic SendResult sendWithTemplate(String phone, String templateId, Map<String, String> params) {// 实现模板短信发送return new SendResult(true, "阿里云模板发送成功");}
}
腾讯云实现
@Slf4j
@Service
@ConditionalOnProperty(name = "sms.provider", havingValue = "tencent")
public class TencentSmsService implements SmsService {@Value("${sms.tencent.app-id}")private String appId;@Value("${sms.tencent.app-key}")private String appKey;@Overridepublic SendResult send(String phone, String content) {// 腾讯云短信发送实现log.info("使用腾讯云短信平台发送短信至:{}", phone);// 实际调用腾讯云SDKreturn new SendResult(true, "腾讯云发送成功");}@Overridepublic SendResult sendWithTemplate(String phone, String templateId, Map<String, String> params) {// 实现模板短信发送return new SendResult(true, "腾讯云模板发送成功");}
}
短信服务工厂
@Component
public class SmsServiceFactory {private final Map<String, SmsService> smsServiceMap;@Autowiredpublic SmsServiceFactory(List<SmsService> smsServices) {smsServiceMap = new HashMap<>();for (SmsService service : smsServices) {String providerName = resolveProviderName(service.getClass());smsServiceMap.put(providerName, service);}}public SmsService getSmsService(String provider) {return smsServiceMap.get(provider);}private String resolveProviderName(Class<?> clazz) {// 解析类名或注解获取提供商名称if (clazz.getSimpleName().toLowerCase().contains("aliyun")) {return "aliyun";} else if (clazz.getSimpleName().toLowerCase().contains("tencent")) {return "tencent";}return clazz.getSimpleName();}
}
统一门面服务
@Service
public class UnifiedSmsService {@Autowiredprivate SmsServiceFactory smsServiceFactory;@Value("${sms.provider:aliyun}")private String currentProvider;public SendResult sendSms(String phone, String content) {SmsService service = smsServiceFactory.getSmsService(currentProvider);return service.send(phone, content);}public SendResult sendTemplateSms(String phone, String templateId, Map<String, String> params) {SmsService service = smsServiceFactory.getSmsService(currentProvider);return service.sendWithTemplate(phone, templateId, params);}
}

3. 配置示例

application.yml

# 短信服务配置
sms:provider: aliyun  # 可切换为 tencent# 阿里云配置aliyun:access-key-id: your-access-key-idaccess-key-secret: your-access-key-secretsign-name: your-sign-name# 腾讯云配置tencent:app-id: your-app-idapp-key: your-app-keysign-name: your-sign-name

4. 业务调用示例

@RestController
@RequestMapping("/sms")
public class SmsController {@Autowiredprivate UnifiedSmsService unifiedSmsService;@PostMapping("/send")public ResponseEntity<SendResult> sendSms(@RequestParam String phone, @RequestParam String content) {// 业务代码无需关心具体实现SendResult result = unifiedSmsService.sendSms(phone, content);return ResponseEntity.ok(result);}
}

方案优势

  1. 解耦设计:业务代码与具体短信平台实现完全解耦
  2. 平滑切换:只需修改配置文件中sms.provider的值即可切换平台
  3. 易于扩展:新增短信平台只需添加新实现类,无需修改现有代码
  4. 集中管理:所有短信平台配置统一管理,便于维护
  5. 条件装配:使用@ConditionalOnProperty确保只有激活的配置才会被加载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920511.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信息技术发展

信息技术是研究如何获取信息、处理信息、传输信息和使用信息的技术。计算机硬件控制器、运算器、存储器、输入设备、输出设备。计算机软件系统软件、应用软件、中间件。通信系统包括源系统、传输系统、目的系统。网络基础 个人局域网、局域网、城域网、广域网、公用网、专用网。…

2023年12月GESP5级C++真题解析,包括选择判断和编程

一、选择题&#xff08;每道题2分&#xff0c;共30分&#xff09; 1、下面C代码用于求斐波那契数列&#xff0c;该数列第1 、2项为1&#xff0c;以后各项均是 前两项之和。下面有关说法错误的是( ) A. fiboA( ) ⽤递归⽅式&#xff0c;fiboB() 循环⽅式 B. fiboA( ) 更加符合…

C++ 面试高频考点 力扣 704.二分查找 基础二分查找 题解 每日一题

文章目录二分查找&#xff1a;从基础原理到代码实现二分查找的特点算法重点题目描述&#xff1a;LeetCode 704. 二分查找为什么可以用二分查找&#xff1f;暴力算法解法二分查找解法核心逻辑&#xff1a;三种情况的处理二分查找什么时候结束&#xff1f;为什么二分查找一定是对…

《UE5_C++多人TPS完整教程》学习笔记45 ——《P46 待机与跳跃动画(Idle And Jumps)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P46 待机与跳跃动画&#xff08;Idle And Jumps&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09…

2025年03月 Scratch 图形化(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch图形化等级考试(1~4级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 气球初始位置如下图所示,运行下列程序,气球会朝哪个方向移动?( ) A:水平向右 B:垂直向下 C:水平向左 D:垂直向上 答案:A 气球水平向右移动 第2题 使用下列哪个选项可以将…

android 不同分辨图片放错对应文件夹会怎样?

多年前有人问过我这个问题&#xff0c;当时没太了解这个东西&#xff0c;觉得是无所谓的东西&#xff0c;不过没答上来这个问题还是让我记了很久。今天又看到有人发文章讨论这个问题&#xff0c;我也就特意再研究下。1&#xff0c;了解一下Android分辨率是什么。2&#xff0c;同…

48.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--解决Refit接口调用未授权的访问问题

我们在项目中集成了Refit&#xff0c;但是在调用接口时&#xff0c;出现了问题&#xff0c;提示未授权的访问。这个问题是怎么导致的呢&#xff1f;我们该怎么处理呢&#xff1f;在这篇文章中我们一起来解决吧。 一、为什么会出现这个问题 让我们来深入分析一下是哪里返回的未授…

nacos登录认证

先看一个现象bootstrap.yml配置如下&#xff1a;spring:application:name: myservicecloud:nacos:discovery:server-addr: 127.0.0.1:8848username: nacospassword: nacosconfig:prefix: testfile-extension: ymlusername: nacos123password: nacos注意&#xff1a;配置中nacos…

论文阅读:arixv 2025 WideSearch: Benchmarking Agentic Broad Info-Seeking

WideSearch&#xff1a;大规模信息检索基准测试 https://arxiv.org/pdf/2508.07999 字节&#xff1a;Agent大规模信息获取基准WideSearch WideSearch&#xff1a;揭示 AI 智能体缺失的「广度」能力 Project Page: https://widesearch-seed.github.io/ get the data&#x…

【Docker基础】Docker-compose进阶配置:资源限制与高可用部署

目录 引言 1 Docker资源限制基础概念 1.1 为什么需要资源限制 1.2 Docker资源限制的类型 2 CPU与内存资源限制配置 2.1 传统资源限制方式&#xff08;version 2&#xff09; 2.2 现代资源限制方式&#xff08;version 3 deploy.resources&#xff09; 关键参数解释&…

SQL优化--OR

优化 SQL 中的 OR 条件是一个非常常见的性能调优问题。OR 操作符经常会导致性能下降&#xff0c;因为它使得数据库优化器难以高效地使用索引。下面我将从浅入深地为你讲解优化 OR 的多种策略&#xff0c;并附上示例。为什么 OR 性能往往较差&#xff1f;在简单的 WHERE 子句中&…

Java试题-选择题(21)

Java试题-选择题(21) 题目 有关线程的叙述正确的是 ? A:可以获得对任何对象的互斥锁定 B:通过继承Thread类或实现Runnable接口,可以获得对类中方法的互斥锁定 C:线程通过使用synchronized关键字可获得对象的互斥锁定 D:线程调度算法是平台独立的 下面有关forward和re…

预测模型及超参数:3.集成学习:[1]LightGBM

想象你是一位乐队指挥&#xff0c;你的任务是协调乐队中的每位音乐家&#xff0c;以演奏出一场完美的音乐会。每位音乐家&#xff08;即决策树&#xff09;擅长不同的乐器或乐章。在指挥过程中&#xff0c;你通过调节各位音乐家演奏的强度&#xff08;模型参数&#xff09;&…

Jetson进行旋转目标检测推理实现大疆无人机飞行控制

源码结构 大疆PSDK源码地址&#xff1a; https://github.com/dji-sdk/Payload-SDK其目录结构如下&#xff1a; Payload-SDK-master ├── CMakeLists.txt ├── doc │ ├── dji_sdk_code_style │ └── simple_model ├── EULA.txt ├── LICENSE.txt ├── psd…

阿里云百炼智能体连接云数据库实践(DMS MCP)

这篇文章主要是通过使用阿里云的百炼智能体与阿里云的serverless来实现数据库的操作 欢迎一起交流&#xff01;&#xff01; 首先&#xff0c;当然是选择自己需要的数据库啦 在阿里云控制台选择产品 - > 数据库 - > 数据管理DMS进来的界面如下所示 第一次进来的时候是…

某商店JS混淆补环境与纯算逆向分析

文章目录1. 写在前面2. 接口分析3. 补环境分析4. 纯算法还原【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并…

如何安装 mysql-installer-community-8.0.21.0.tar.gz(Linux 详细教程附安装包下载)​

这是一个 ​Linux 下 MySQL 8.0.21 的压缩安装包&#xff0c;虽然名字里有 installer&#xff0c;但它其实就是一个压缩好的二进制安装包&#xff0c;不是 Windows 那种图形化安装程序。 一、准备工作 确保你已经有&#xff1a; Linux 系统&#xff08;比如 Ubuntu、CentOS、…

IDEA-琴澳研究中心及学术联盟启动,产研协同赋能区域发展

8月30日&#xff0c;IDEA-琴澳中心主导研发的Smaray渲染引擎将发布可免费下载的Tech Preview&#xff08;技术预览版&#xff09;。本次发布标志着粤港澳大湾区在政产研协同创新实现成果落地&#xff0c;也是产业“人工智能”的探索迈进。Smaray是国内首个公开服务的、AI驱动的…

如何备份 TECNO 手机上的短信

许多 TECNO 用户都在寻找方法&#xff0c;以防止因手机损坏、被盗或恢复出厂设置而导致重要对话意外丢失&#xff0c;确保在需要时能够访问他们的数据。还有些人希望在释放设备存储空间的同时&#xff0c;仍然保留旧消息的副本以供日后参考。如果你一直在寻找“备份 TECNO 短信…

OpenAI Sora深度解析:AI视频生成技术如何重塑广告电商行业?影业合作已落地

最近刷到一条超震撼的视频&#xff1a;咖啡杯从桌角滑落&#xff0c;在空中转了半圈居然自己弹回桌面&#xff0c;牛奶一滴没洒。你猜怎么着&#xff1f;这居然是AI生成的&#xff0c;就是OpenAI那个叫Sora的工具做的。是不是觉得有点不可思议&#xff1f;现在这技术已经能做到…