当前位置: 首页 > backend >正文

CouponHub项目开发记录-基于责任链来进行创建优惠券模板的参数验证

什么是责任链

责任链是一种设计模式,是让请求沿着一条处理链进行传递,从而让这条责任链上的对象来对该请求进行处理。

Controller层
在这里插入图片描述
进入service层中的创建优惠券模板方法
在这里插入图片描述
首先可以看到他调用了责任链上下文对象的handler处理方法,我们再进入对象内部
在这里插入图片描述

  • 首先可以看到他注入了一个ApplicationContext对象,通过该对象可以获取到SpringIOC当中的Bean。
  • 接着他定义了一个Map作为容器保存一个责任链,key为mark,value创建的责任链对象集合

在这里插入图片描述
接着再看其中的run方法

  • 首先他去通过applicationContext去获取实现了责任链接口的类构成的bean
  • 然后去遍历获取到的这个存放着所有实现了该接口的bean集合,并判断责任链容器中是否有带该mark标识的bean,如果有则直添加到其中,如果没有,创建一个List集合,然后再放入容器当中

在这里插入图片描述
再接着看它的handler方法

  • 首先根据传入的mark到容器中去找这一组责任链
  • 然后遍历这一组责任链上的对象分别调用他们的handler方法

在这里插入图片描述
看这些责任链对象的具体实现
在这里插入图片描述
直接实现MerchantAdminAbstractChainHandler接口,实现里面的handler方法。

// 新增优惠券模板信息到数据库CouponTemplateDO couponTemplateDO = BeanUtil.toBean(requestParam, CouponTemplateDO.class);couponTemplateDO.setStatus(CouponTemplateStatusEnum.ACTIVE.getStatus());couponTemplateDO.setShopNumber(UserContext.getShopNumber());couponTemplateMapper.insert(couponTemplateDO);// 因为模板 ID 是运行中生成的,@LogRecord 默认拿不到,所以我们需要手动设置LogRecordContext.putVariable("bizNo", couponTemplateDO.getId());// 缓存预热:通过将数据库的记录序列化成 JSON 字符串放入 Redis 缓存CouponTemplateQueryRespDTO actualRespDTO = BeanUtil.toBean(couponTemplateDO, CouponTemplateQueryRespDTO.class);Map<String, Object> cacheTargetMap = BeanUtil.beanToMap(actualRespDTO, false, true);Map<String, String> actualCacheTargetMap = cacheTargetMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,entry -> entry.getValue() != null ? entry.getValue().toString() : ""));String couponTemplateCacheKey = String.format(MerchantAdminRedisConstant.COUPON_TEMPLATE_KEY, couponTemplateDO.getId());// 通过 LUA 脚本执行设置 Hash 数据以及设置过期时间String luaScript = "redis.call('HMSET', KEYS[1], unpack(ARGV, 1, #ARGV - 1)) " +"redis.call('EXPIREAT', KEYS[1], ARGV[#ARGV])";List<String> keys = Collections.singletonList(couponTemplateCacheKey);List<String> args = new ArrayList<>(actualCacheTargetMap.size() * 2 + 1);actualCacheTargetMap.forEach((key, value) -> {args.add(key);args.add(value);});// 优惠券活动过期时间转换为秒级别的 Unix 时间戳args.add(String.valueOf(couponTemplateDO.getValidEndTime().getTime() / 1000));// 执行 LUA 脚本stringRedisTemplate.execute(new DefaultRedisScript<>(luaScript, Long.class),keys,args.toArray());

之后就是将该优惠券模板放入数据库当中,然后再存入到Redis当中进行缓存预热。

在这里插入图片描述
之后还有创建延时修改优惠券的时间,并通过消息队列进行发送,优惠券到期以后自动修改优惠券状态。

还有为了解决缓存穿透问题而将创建的优惠券模板id放入布隆过滤器当中。

布隆过滤器的原理

布隆过滤器是通过N个哈希函数和一个位图数组构成。当将id放入布隆过滤器后,会通过N个哈希函数去计算哈希值,再与位图数组的长度进行取模运算。得到在位图数组中的位置。然后下次再去查询数据库之前会先查看布隆过滤器中是否有该数据。如果每个对应的位置都为一,则可能存在(因为哈希冲突)。如果存在一个为0则一定不存在。

http://www.xdnf.cn/news/19728.html

相关文章:

  • Django get_or_create 方法详解
  • centos9 docker启动不起来,docker启动发生堵塞问题!
  • 少儿舞蹈小程序(6)打造您的“活”名片:动态展示机构实力
  • MySQL的utf8 、utf8mb3 和 utf8mb4 的区别和排序规则
  • Python 工具: Windows 带宽监控工具
  • JavaScript考核
  • Tomcat 全面指南:从目录结构到应用部署与高级配置
  • mit6.031 2023spring 软件构造 笔记 Specification
  • 【LeetCode 热题 100】1143. 最长公共子序列——(解法二)递推
  • 2025 大学生职业准备清单:从数据到财会,这些核心证书值得考
  • 【IO】多进程编程课后练习
  • 单多行文本溢出
  • Selenium核心技巧:元素定位与等待策略
  • ArkUI核心功能组件使用
  • 【线段树】3525. 求出数组的 X 值 II|2645
  • Spring 事务原理解析:AOP 的一次完美落地
  • 深度学习——基于卷积神经网络实现食物图像分类【4】(使用最优模型)
  • 广度优先搜索(BFS, Breadth-First Search)
  • 数字化转型的六大天问:你的项目为何失败
  • 数据开发工作了一年,准备跳槽,回顾一些面试常见问题,大数据面试题汇总与答案分享
  • 【3D打印】3D打印机首次使用心得
  • 2025最新“Java 面试八股文 + 各大厂的面试真题”限时开源
  • 人工智能助力流感疫苗选择:MIT 团队推出 VaxSeer 系统
  • Understanding the Flap T in American English
  • 开源企业级快速开发平台(JeecgBoot)
  • Python闭包机制:原理、应用与安全防护
  • 【Doris入门】Doris数据表模型:聚合模型(Aggregate Key Model)详解
  • java-设计模式-4-创建型模式-工厂
  • 【52页PPT】服务业数字化转型如何做(附下载方式)
  • Ubuntu 用户和用户组