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

基于erp业务的责任链模式实战

Handler接口是用来规范所有的责任链节点都要实现 处理数据的方法 AbstractSchHandlerContains
是责任链节点保存的抽象类 ScheduleHandlerContains
子类可以覆盖责任链节点保存容器实现自定义遍历责任链节点容器方法设置自定义容器

一. 创建责任链节点接口 用于规范责任链的处理方法

public interface Handler {void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler);
}

二. 创建具体责任链节点

  1. 拉取erp业务数据节点
public class PullSchDataHandler implements Handler {public final ExecutorService executor = Executors.newFixedThreadPool(9);@BeanField(beanName = "xxxService",beanType = xxxService.class)private PullScheduleMetadataService pullScheduleMetadataService;@Overridepublic void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler) {//使用executor拉取WMS的仓储信息 并且保存在schedules集合中schedules.addAll('erp业务详情');//传递到下一个节点abstractSchHandler.doHandler(schedules, cursor,abstractSchHandler);}
}
  1. 判断erp信息节点
public class SwitchHandler implements Handler {@Overridepublic void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler) {schedules.forEach(a -> {//做数据判断 然后再传递给下一个节点});abstractSchHandler.doHandler(schedules, cursor,abstractSchHandler);}
}
  1. 整理erp信息到数据流中
public class ColHandler implements Handler {@BeanField(beanName = "xxxMapper", beanType = xxxMapper.class)private xxxMapper xxxMapper;@Overridepublic void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler) {//获取信息传递到下一个节点schedules.addAll('协助信息');abstractSchHandler.doHandler(schedules, cursor,abstractSchHandler);}
}
  1. 保存数据
public class SaveHandler implements Handler {@BeanField(beanName = "xxxMapper", beanType = xxxMapper.class)private xxxMapper xxxMapper;@Overridepublic void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler) {//保存数据int i = xxxMapper.saveAll(schedules);abstractSchHandler.doHandler(schedules, cursor,abstractSchHandler);}
}

三. 责任链节点容器

  1. 抽象节点容器
public abstract class AbstractSchHandlerContains implements Handler {//责任链节点容器protected List<Handler> filtersChain = new ArrayList<>();public List<Handler> getFiltersChain() {return filtersChain;}public void setFiltersChain(List<Handler> filtersChain) {this.filtersChain = filtersChain;}@Overridepublic void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler) {//遍历责任链//判断是否遍历到责任链容器的末尾if (cursor < filtersChain.size()) {//获取责任链容器中的节点Handler handler = filtersChain.get(cursor);//移动游标cursor++;//执行节点的业务逻辑handler.doHandler(schedules, cursor, abstractSchHandler);//责任链递归回来后执行代码区域}}
}
  1. 具体责任链节点容器
public class ScheduleHandlerContains extends AbstractSchHandlerContains
{@Overridepublic List<Handler> getFiltersChain() {return super.getFiltersChain();}@Overridepublic void setFiltersChain(List<Handler> filtersChain) {super.setFiltersChain(filtersChain);}@Overridepublic void doHandler(List<Schedule> schedules, Integer cursor,AbstractSchHandlerContains abstractSchHandler) {//实现自定义的遍历节点方法super.doHandler(schedules, cursor, abstractSchHandler);}
}

四. 获取责任链容器节点的门面类

自定义注解再结合 ApplicationContextAware 接口获得spring容器 使用反射设置对象的成员变量
handlerType的值

@Slf4j
@Component
public class ScheduleChainBuilderFaced implements ApplicationContextAware {//责任链节点控制变量//用来控制责任链节点的顺序与 责任链是否重构的变量//duty.chain默认值是pullData,judDoc,collaborate,saveData@Value("${duty.chain}")private volatile String handlerType;//记录当前handlerType的配置,判断duty.chain的配置是否有修改//如果有修改,说明duty.chain的配置有修改,需要从新初始化责任链条private String currentHandlerType;//记录责任链节点的成员变量private AbstractSchHandlerContains handlerList;//spring容器private ApplicationContext springContext;//重写ApplicationContextAware接口的方法 用于获取spring容器@Overridepublic void setApplicationContext(ApplicationContext applicationContext)throws BeansException {this.springContext = applicationContext;}//获取责任链容器的方法public AbstractSchHandlerContains buildChainByList() {//如果没有配置,直接返回nullif (handlerType == null) {return null;}//如果是第一次配置,将handlerType记录下来if (currentHandlerType == null) {this.currentHandlerType = this.handlerType;}currentHandlerif (this.handlerType.equals(currentHandlerType) && this.handlerList!= null) {return handlerList;} else { synchronized (this) {//双检锁 保证线程安全if (this.handlerType.equals(currentHandlerType) &&this.handlerList != null) {return handlerList;}try {log.info("配置有修改或首次初始化,组装责任链条!!!");//创建责任链容器handlerList = new ScheduleHandlerContains();List<String> handlerTypeList =Arrays.asList(handlerType.split(","));//获取自定义注解中的值 用来初始化责任链节点中的成员变量for (String handlerType : handlerTypeList) {//获取字节码对象Class<?> aClass =Class.forName(HandlerEnumByList.valueOf(handlerType).getValue());//创建对象Handler handler = (Handler) aClass.newInstance();//获取注解for (Field declaredField :aClass.getDeclaredFields()) {//获取自定义注解中的值BeanField annotation =declaredField.getAnnotation(BeanField.class);if (!Objects.isNull(annotation)) {//获取注解中的值String requireBeanName =annotation.beanName();Class<?> requireBeanType =annotation.beanType();//从spring容器中获取Object bean =springContext.getBean(requireBeanName, requireBeanType);declaredField.setAccessible(true);//给成员变量赋值declaredField.set(handler, bean);}}//加入责任链节点容器中 //默认加入ArrayList中handlerList.getFiltersChain().add(handler);}//从新赋值修改后的配置this.currentHandlerType = this.handlerType;// 返回责任链条return handlerList;} catch (Exception e) {throw new UnsupportedOperationException(e);}}}}
}

五. 创建时元数据

public enum HandlerEnumByList {collaborate("com.xxx.schedutychain.handlers.ColHandler"),judDoc("com.xxx.schedutychain.handlers.SwitchHandler"),pullData("com.xxx.schedutychain.handlers.PullSchDataHandler"),saveData("com.xxx.schedutychain.handlers.SaveHandler");String value = "";HandlerEnumByList(String value) {this.value = value;}public String getValue() {return this.value;}
}

六. 自定义成员变量注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BeanField {String beanName() default "";Class<?> beanType() ;
}

七. 调用接口

@Resource
private ScheduleChainBuilderFaced scheduleChainBuilderFaced;@GetMapping("/xxxx")
@ResponseBody
@Transactional
public void xxxxSchedule() {AbstractSchHandlerContains scheduleHandler =scheduleChainBuilderFaced.buildChainByList();ScheduleHandler.doHandler(new ArrayList<>(), 0, scheduleHandler);
}

相关文章:

  • 设计模式:责任链模式示例
  • 线上研讨会 | 新一代数字化技术赋能机器人及智能产线行业高质量发展
  • 2024 蓝桥打卡Day35
  • 算法训练营第35天|LeetCode 860.柠檬水找零 406.根据身高重建队列 452.用最少数量的箭引爆气球
  • Vue2 —— 学习(一)
  • JAVA POI Excel 使用数组公式 FREQUENCY
  • 2024.4.2力扣每日一题——所有可能的真二叉树
  • Word文档如何设置单选框、复选框、下拉框
  • python selenium向html中写入内容
  • Spring、SpringMVC、Springboot三者的区别和联系
  • 深入理解JVM后端优化技术-逃逸分析(Escape Analysis)
  • 【牛客SQL快速入门】SQL基础(一)
  • 蓝桥杯-网络安全比赛(5)基础学习-JavaScript原型链的prototype、constructor、object.create()、__proto__
  • go语言学习--2.函数
  • 为什么 MySQL 采用 B+ 树作为索引?
  • 【5+】跨webview多页面 触发事件(二)
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • angular2 简述
  • extjs4学习之配置
  • React-生命周期杂记
  • springboot_database项目介绍
  • Yeoman_Bower_Grunt
  • - 概述 - 《设计模式(极简c++版)》
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 计算机常识 - 收藏集 - 掘金
  • 今年的LC3大会没了?
  • 利用jquery编写加法运算验证码
  • 两列自适应布局方案整理
  • 数据科学 第 3 章 11 字符串处理
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​iOS安全加固方法及实现
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #FPGA(基础知识)
  • #Lua:Lua调用C++生成的DLL库
  • ()、[]、{}、(())、[[]]命令替换
  • (09)Hive——CTE 公共表达式
  • (二)pulsar安装在独立的docker中,python测试
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (三)终结任务
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)setTimeout 和 setInterval 的区别
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .NET开发者必备的11款免费工具
  • .NET中使用Protobuffer 实现序列化和反序列化
  • .考试倒计时43天!来提分啦!
  • @media screen 针对不同移动设备
  • @基于大模型的旅游路线推荐方案
  • [.net]官方水晶报表的使用以演示下载
  • [145] 二叉树的后序遍历 js
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息