责任链模式+CompletableFuture异步处理

1、查询商品基础信息
2、查询商品价格
3、查询商品活动
4、查询商品库存

假设这几个服务逻辑比较独立,其实是可以并行调用,我们可以结合责任链模式和CompletableFuture进行优化:

下面是代码示例:
在这里插入图片描述


@Service
public class ChainFactory {// 原型模式获取对象@Resourceprivate  Map<String, ILogicChain> strategyChainGroup;public ChainFactory(Map<String, ILogicChain> strategyChainGroup) {this.strategyChainGroup = strategyChainGroup;}/*** 构建责任链并获取所有处理器的 CompletableFuture 数组** @param productInfo 商品信息对象* @return CompletableFuture 数组*/public CompletableFuture<Void>[] openLogicChain(ProductInfo productInfo) {// 按照配置顺序装填责任链;ILogicChain logicChain = strategyChainGroup.get(LogicModel.BASIC_INFO_SERVICE_HANDLER.getCode());ILogicChain current = logicChain;List<CompletableFuture<Void>> futures = new ArrayList<>();//遍历LogicModel的codeLogicModel[] ruleModels = LogicModel.values();for (int i = 1; i < ruleModels.length; i++) {ILogicChain nextChain = strategyChainGroup.get(ruleModels[i].getCode());current.appendNext(nextChain);}// 获取所有处理器的 CompletableFuturecurrent = logicChain;while (current != null) {CompletableFuture<Void> future = current.logic(productInfo);futures.add(future);current = current.next();}return futures.toArray(new CompletableFuture[0]);}@Getter@AllArgsConstructorpublic enum LogicModel {BASIC_INFO_SERVICE_HANDLER("basicInfoServiceHandler", "实现商品基础信息补全节点"),PRICE_SERVICE_HANDLER("priceServiceHandler", "实现商品价格补全节点"),ACTIVITY_SERVICE_HANDLER("activityServiceHandler", "实现商品活动补全节点"),INVENTORY_SERVICE_HANDLER("inventoryServiceHandler", "实现商品库存服务节点");private final String code;private final String info;}}

@Slf4j
@Component("activityServiceHandler")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ActivityServiceHandler extends AbstractLogicChain {@Overridepublic CompletableFuture<Void> logic(ProductInfo productInfo) {CompletableFuture<Void> future = new CompletableFuture<>();// 模拟异步调用外部服务,修改商品信息对象CompletableFuture.runAsync(() -> {// 补充商品活动数据productInfo.setActivity("...");//休眠10秒try {TimeUnit.SECONDS.sleep(10);log.info("activityServiceHandler logic 结束:{}",now());} catch (InterruptedException e) {e.printStackTrace();}future.complete(null);});return future;}}

@Slf4j
@Component("basicInfoServiceHandler")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class BasicInfoServiceHandler extends AbstractLogicChain {@Overridepublic CompletableFuture<Void> logic(ProductInfo productInfo) {CompletableFuture<Void> future = new CompletableFuture<>();// 模拟异步调用外部服务,修改商品信息对象CompletableFuture.runAsync(() -> {// 补充商品基础信息数据productInfo.setBasicInfo("...");//休眠10秒try {TimeUnit.SECONDS.sleep(10);log.info("basicInfoServiceHandler logic 结束:{}",now());} catch (InterruptedException e) {e.printStackTrace();}future.complete(null);});return future;}}

@Slf4j
@Component("inventoryServiceHandler")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class InventoryServiceHandler extends AbstractLogicChain {@Overridepublic CompletableFuture<Void> logic(ProductInfo productInfo) {CompletableFuture<Void> future = new CompletableFuture<>();// 模拟异步调用外部服务,修改商品信息对象CompletableFuture.runAsync(() -> {// 补充商品库存数据productInfo.setInventory(100);//休眠10秒try {TimeUnit.SECONDS.sleep(10);log.info("inventoryServiceHandler logic 结束:{}",now());} catch (InterruptedException e) {e.printStackTrace();}future.complete(null);});return future;}
}

@Slf4j
@Component("priceServiceHandler")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PriceServiceHandler extends AbstractLogicChain {@Overridepublic CompletableFuture<Void> logic(ProductInfo productInfo) {CompletableFuture<Void> future = new CompletableFuture<>();// 模拟异步调用外部服务,修改商品信息对象CompletableFuture.runAsync(() -> {// 补充商品价格数据productInfo.setPrice(100.0);//休眠10秒try {TimeUnit.SECONDS.sleep(10);log.info("priceServiceHandler logic 结束:{}",now());} catch (InterruptedException e) {e.printStackTrace();}future.complete(null);});return future;}}

@Data
public class ProductInfo {//模拟商品基础信息private String basicInfo;//商品价格private double price;//模拟商品活动信息private String activity;//模拟商品库存private int inventory;// 省略构造函数、getter和setter
}

@Slf4j
public abstract class AbstractLogicChain implements ILogicChain {private ILogicChain next;@Overridepublic ILogicChain next() {return next;}@Overridepublic ILogicChain appendNext(ILogicChain next) {this.next = next;return next;}}
public interface ILogicChain extends ILogicChainArmory, Cloneable {/*** 责任链接口** @param productInfo    请求对象* @return*/CompletableFuture<Void> logic(ProductInfo productInfo);}
public interface ILogicChainArmory {ILogicChain next();ILogicChain appendNext(ILogicChain next);}

测试类

@Resourceprivate ChainFactory chainFactory;@Testpublic void testAsyncChain() {// 创建一个 ProductInfo 对象ProductInfo productInfo = new ProductInfo();// 获取所有处理器的 CompletableFuture 数组CompletableFuture<Void>[] futures = chainFactory.openLogicChain(productInfo);// 等待所有责任链处理完成CompletableFuture.allOf(futures).join();log.info("结束");}

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

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

相关文章

GloVe: Global Vectors for Word Representation论文笔记解读

基本信息 作者Jeffrey Penningtondoi10.3115/v1/D14-1162发表时间2014期刊EMNLP网址https://aclanthology.org/D14-1162.pdf 研究背景 1. What’s known 既往研究已证实 全局矩阵分解方法&#xff1a;LSA&#xff0c;考虑整个语料库词频的统计信息得到共现矩阵&#xff0c;通…

Spring Security学习笔记(一)Spring Security架构原理

前言&#xff1a;本系列博客基于Spring Boot 2.6.x依赖的Spring Security5.6.x版本 Spring Security中文文档&#xff1a;https://springdoc.cn/spring-security/index.html 一、什么是Spring Security Spring Security是一个安全控制相关的java框架&#xff0c;它提供了一套全…

昇思25天学习打卡营第1天 | 基本介绍

打卡&#xff1a; 小白一个&#xff0c;第一次接触昇思MindSpore&#xff0c;之前使用chatgpt较多一点。这次相当于从使用着角色转换成制作者的角色&#xff0c;跨度比较大。如果之前没有接触过相关内容&#xff0c;学习起来还是比较费劲。 基本介绍&#xff1a; 昇思MindSpo…

ValueError和KeyError: ‘bluegrass’的问题解决

项目场景&#xff1a; 项目相关背景&#xff1a; 问题描述 遇到的问题1&#xff1a; KeyError: ‘bluegrass’ 不能识别某标签 遇到的问题2&#xff1a; xml etree.fromstring(xml_str) ValueError: Unicode strings with encoding declaration are not supported. Please …

K8S 中的 CRI、OCI、CRI shim、containerd

K8S 如何创建容器&#xff1f; 下面这张图&#xff0c;就是经典的 K8S 创建容器的步骤&#xff0c;可以说是冗长复杂&#xff0c;至于为什么设计成这样的架构&#xff0c;继续往下读。 前半部分 CRI&#xff08;Container Runtime Interface&#xff0c;容器运行时接口&#xf…

PCIe驱动开发(3)— 驱动设备文件的创建与操作

PCIe驱动开发&#xff08;3&#xff09;— 驱动设备文件的创建与操作 一、前言 在 Linux 中一切皆为文件&#xff0c;驱动加载成功以后会在“/dev”目录下生成一个相应的文件&#xff0c;应用程序通过对这个名为“/dev/xxx” (xxx 是具体的驱动文件名字)的文件进行相应的操作即…

元宇宙深入解析

元宇宙&#xff08;Metaverse&#xff09;是一个新兴的概念&#xff0c;它激发了技术专家、艺术家和商业领袖的无限想象。它代表着数字互动的新前沿&#xff0c;提供了一个平行的数字宇宙&#xff0c;用户可以在其中实时互动&#xff0c;超越物理世界的限制。 元宇宙是什么&am…

安防视频监控/视频汇聚EasyCVR平台浏览器http可以播放,https不能播放,如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构&#xff0c;兼容性强、支持多协议接入&#xff0c;包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…

链接追踪系列-00.es设置日志保存7天-番外篇

索引生命周期策略 ELK日志我们一般都是按天存储&#xff0c;例如索引名为"zipkin-span-2023-03-24"&#xff0c;因为日志量所占的存储是非常大的&#xff0c;我们不能一直保存&#xff0c;而是要定期清理旧的&#xff0c;这里就以保留7天日志为例。 自动清理7天以前…

Python基础语法篇(上)

Python基础语法&#xff08;上&#xff09; 一、基知二、基本数据类型&#xff08;一&#xff09;标准数据类型&#xff08;二&#xff09;数据类型转换 三、字符串基本操作&#xff08;一&#xff09;字符串的索引和切片&#xff08;二&#xff09;字符串的拼接 三、运算符四、…

【React笔记初学总结一】React新手的学习流程笔记总结,掰开了揉碎了,下载安装基础结构学习

REACT学习记录 一、React是什么&#xff1a;二、尝试安装下载&#xff1a;三、理解都有什么四、基础网页学习&#xff1a;1.几个比较重要的资源包例子2.第一个react示例&#xff1a;&#xff08;掰开了揉碎了&#xff0c;咱们先看懂它最简单的结构&#xff09;3.第二个react示例…

2.10、matlab中字符、数字、矩阵、字符串和元胞合并为字符串并将字符串以不同格式写入读出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的数据类型&#xff08;字符、数字、矩阵、字符串和元胞&#xff09;合并为字符串&#xff0c;然后将字符串以不同格式写入 Excel 文件。 以下是一个示例代码&#xff0c;展示如何将不同数据类型合并为字符串&#xff0c;并以不…

一五六、Node+Vue 使用七牛上传图片,并配置个人域名

1. 七牛云ak/sk获取 点击注册&#x1f517;开通七牛开发者帐号如果已有账号&#xff0c;直接登录七牛开发者后台&#xff0c;点击这里&#x1f517;查看 Access Key 和 Secret Key 2. Node.js获取七牛token 安装qiniu npm install qiniu创建空间 Node获取token const qi…

Excel办公技巧:制作二级联动下拉菜单

分享制作二级联动下拉菜单的方法&#xff0c;即使数据有增删&#xff0c;菜单也能自动更新&#xff01; 可以通过先定义名称&#xff0c;再结合数据验证&#xff0c;来做二级联动下拉菜单。 1. 准备数据 首先&#xff0c;我们需要准备好要进行二级联动下拉菜单的数据&#xff…

PGCCC|【PostgreSQL】PCA+PCP+PCM等IT类认证申报个税退税指南

小编特将PostgreSQL证书申报个税退税流程&#xff0c;编辑成文&#xff0c;供大家申报参考哦~ 1.申报专项附加扣除 第一步&#xff1a;打开个人所得税APP&#xff0c;选择“专项附加扣除填报”&#xff1a; 第二步&#xff1a;“扣除年度”选择您要申报的年度&#xff0c;并…

韦东山嵌入式linux系列-具体单板的 LED 驱动程序

笔者使用的是STM32MP157的板子 1 怎么写 LED 驱动程序&#xff1f; 详细步骤如下&#xff1a; ① 看原理图确定引脚&#xff0c;确定引脚输出什么电平才能点亮/熄灭 LED ② 看主芯片手册&#xff0c;确定寄存器操作方法&#xff1a;哪些寄存器&#xff1f;哪些位&#xff1f;…

AI+折叠屏,荣耀的创新周期论

文&#xff5c;刘俊宏 编&#xff5c;王一粟 2024年&#xff0c;AI和折叠屏的演进路线&#xff0c;已经成为了手机行业的共识。 首先&#xff0c;手机市场的新增量已经被折叠屏所接管。据Counterpoint Research数据显示&#xff0c;中国2024年第一季度折叠屏手机销量同比增长…

怎样把视频压缩小一点 视频压缩工具

在数字媒体时代&#xff0c;视频文件的传输与分享已成为日常。然而&#xff0c;大视频文件往往给存储和分享带来诸多不便。如何将视频压缩到最小&#xff0c;同时保持画质和音质&#xff0c;成为了许多用户关注的焦点。本文将为你揭秘一系列高效的视频压缩方法&#xff0c;让你…

Linux离线安装Mysql5.7

Linux之Mysql安装配置 第一种&#xff1a;Linux离线安装Mysql&#xff08;提前手动下载好tar.gz包&#xff09; 第二种&#xff1a;通过yum安装配置Mysql&#xff08;服务器有网络&#xff09; 之前在阿里云上采用yum安装过一次&#xff08;请看这里&#xff09;&#xff0c;…

启智畅想火车类集装箱号码识别技术,软硬件解决方案

集装箱号码识别需求&#xff1a; 实时检测车皮号、火车底盘号码、集装箱号码&#xff0c;根据火车类型分为以下三种情况&#xff1a; 1、纯车皮&#xff0c;只检测车皮号&#xff1b; 2、火车拉货箱&#xff08;半车皮&#xff09;&#xff0c;检测车皮号集装箱号码&#xff1b…