聊聊Cola-StateMachine轻量级状态机的实现
Cola-StateMachine组件是一种轻量级的、无状态的、基于注解的状态机实
在分析Seata的saga模式实现时,实在是被其复杂的 json 状态语言定义文件劝退,我是有点没想明白为啥要用这么来实现状态机;盲猜可能是基于可视化的状态机设计器来定制化流程,更方便快捷且上手快吧,毕竟可以通过UI直接操作,设计状态流转图,但我暂时不太能get到。对于Saga模式的实现,之前的博文中已经阐述了基于状态机模式实现Saga,是比较常见且合适的做法,因此了解了下Java中的状态机实现方案,以后有相关的业务场景也可以直接上手使用状态机。
【资料图】
Cola-StateMachineCola-StateMachine组件是一种轻量级的、无状态的、基于注解的状态机实现,可以方便地管理订单等业务对象的状态转换。COLA框架的状态机使用了连贯接口(Fluent Interfaces)来定义状态和事件,以及对应的动作和检查。COLA框架的状态机是COLA 4.0应用架构的一部分,旨在控制复杂度,提高开发效率。开发背景可见实现一个状态机引擎,教你看清DSL的本质。
基础模型在Cola-StateMachine组件中有如下的抽象概念模型:
1.State:状态2.Event:事件,状态由事件触发,引起变化3.Transition:流转,表示从一个状态到另一个状态4.External Transition:外部流转,两个不同状态之间的流转5.Internal Transition:内部流转,同一个状态之间的流转6.Condition:条件,表示是否允许到达某个状态7.Action:动作,到达某个状态之后,可以做什么8.StateMachine:状态机
Cola-StateMachine链路图业务应用示例基于订单业务的场景,做一个简单的demo。
关闭订单的简单流程图
关闭订单简单的状态流转图
添加依赖
com.alibaba.cola cola-component-statemachine 4.3.1
定义一个订单的实体类、订单状态的枚举值、订单事件的枚举值
@Data@Builderpublic class Order { public OrderStatusEnum orderStatusEnum; public Integer orderId; public String orderName;}public enum OrderStatusEnum { INIT("0", "待付款"), WAITING_FOR_DELIVERY("1", "待发货"), HAVE_BEEN_DELIVERY("2", "已发货"), CLOSE("3", "已取消"); private final String code; private final String info; OrderStatusEnum(String code, String info) { this.code = code; this.info = info; } public String getCode() { return code; } public String getInfo() { return info; }}public enum OrderEvent { /** * 用户关闭 */ USER_CLOSE("0", "用户取消"), /** * 管理员关闭 */ ADMIN_CLOSE("1", "后台取消"), /** * 超时关闭 */ OVERTIME_CLOSE("2", "超时取消"), /** * 检查错误关闭 */ CHECK_ERROR_CLOSE("3", "上级审核取消"), /** * 用户付费 */ USER_PAY("4", "用户支付"); /** * 密码 */ private final String code; /** * 信息 */ private final String info; /** * 订单事件 * * @param code 密码 * @param info 信息 */ OrderEvent(String code, String info) { this.code = code; this.info = info; } /** * 获取代码 * * @return {@link String} */ public String getCode() { return code; } /** * 获取信息 * * @return {@link String} */ public String getInfo() { return info; }}
在容器启动的时候注册一个订单状态变更的工厂
@Componentpublic class StateMachineBuilderConfig { @Autowired UserCloseAction userCloseAction; @Bean("orderOperaMachine") public StateMachine orderOperaMachine() { String ORDER_OPERA = "order_opera"; StateMachineBuilder builder = StateMachineBuilderFactory.create(); //订单从初始化状态-待发货-状态-转到-关闭订单状态--用户关闭 builder.externalTransitions() .fromAmong(OrderStatusEnum.INIT, OrderStatusEnum.WAITING_FOR_DELIVERY) .to(OrderStatusEnum.CLOSE) .on(OrderEvent.USER_CLOSE) .when(checkCondition()) .perform(userCloseAction); //订单从-初始化状态-已发货-待发货--转到-关闭订单状态--后台操作人员关闭 builder.externalTransitions() .fromAmong(OrderStatusEnum.INIT, OrderStatusEnum.HAVE_BEEN_DELIVERY, OrderStatusEnum.WAITING_FOR_DELIVERY) .to(OrderStatusEnum.CLOSE) .on(OrderEvent.ADMIN_CLOSE) .when(checkCondition()) .perform(doAction()); //订单从等待发货状态-转为-订单关闭状态-超时关闭 builder.externalTransition() .from(OrderStatusEnum.WAITING_FOR_DELIVERY) .to(OrderStatusEnum.CLOSE) .on(OrderEvent.OVERTIME_CLOSE) .when(checkCondition()) .perform(doAction()); //订单从待发货状态--转为-订单关闭状态-上级审批不通过关闭 builder.externalTransition() .from(OrderStatusEnum.WAITING_FOR_DELIVERY) .to(OrderStatusEnum.CLOSE) .on(OrderEvent.CHECK_ERROR_CLOSE) .when(checkCondition()) .perform(doAction()); //订单从初始化状态--转为待发货状态--用户支付完毕动 builder.externalTransition() .from(OrderStatusEnum.INIT) .to(OrderStatusEnum.WAITING_FOR_DELIVERY) .on(OrderEvent.USER_PAY) .when(checkCondition()) .perform(doAction()); StateMachine orderOperaMachine = builder.build(ORDER_OPERA); //打印uml图 String plantUML = orderOperaMachine.generatePlantUML(); System.out.println(plantUML); return orderOperaMachine; } private Condition checkCondition() { return (ctx) -> { return true; }; } private Action doAction() { return (from, to, event, ctx) -> { System.out.println(ctx.getOrderName() + " 正在操作 " + ctx.getOrderId() + " from:" + from + " to:" + to + " on:" + event); }; }}
在定义一个特殊的,只是举个例子,可以通过集成的方式集成实现一个用户关单的具体操作
@Componentpublic class UserCloseAction implements Action { @Override public void execute(OrderStatusEnum from, OrderStatusEnum to, OrderEvent event, Order context) { System.out.println("用户关闭流程开始走了"); System.out.println("从这个状态-【" + from.getInfo() + "】-转为+【" + to.getInfo() + "】 的状态"); System.out.println("上下文信息:" + context.toString()); System.out.println("中间执行的一些操作......."); System.out.println("用户关闭流程完毕了"); }}
定义一个 controller 的操作接口
@RestControllerpublic class OrderOperaController { @Autowired @Qualifier("orderOperaMachine") StateMachine orderOperaMachine; /** * 场景1-用户关闭订单 * * @return {@link Boolean} */ @RequestMapping("userclose") public Boolean userCloseOrder() { //把订单状态改为关闭 String machineId = orderOperaMachine.getMachineId(); System.out.println(machineId); Order order = Order.builder().orderId(1).orderName("用户").orderStatusEnum(OrderStatusEnum.INIT).build(); OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.INIT,OrderEvent.USER_CLOSE, order); System.out.println(orderStatusEnum.toString()); return true; } /** * 场景2-管理员关闭订单 * * @return {@link Boolean} */ @RequestMapping("adminClose") public Boolean adminCloseOrder() { //把订单状态改为关闭 Order order = Order.builder().orderId(1).orderName("后台操作人员").orderStatusEnum(OrderStatusEnum.HAVE_BEEN_DELIVERY).build(); OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.HAVE_BEEN_DELIVERY, OrderEvent.ADMIN_CLOSE, order); System.out.println(orderStatusEnum.toString()); return true; } /** * 场景3-超时关闭订单 * * @return {@link Boolean} */ @RequestMapping("overTimeclose") public Boolean overTimeCloseOrder() { //把订单状态改为关闭 Order order = Order.builder().orderId(1).orderName("超时了关闭订单") .orderStatusEnum(OrderStatusEnum.WAITING_FOR_DELIVERY).build(); //OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.CLOSE, OrderEvent.OVERTIME_CLOSE, order); OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.WAITING_FOR_DELIVERY, OrderEvent.OVERTIME_CLOSE, order); System.out.println(orderStatusEnum.toString()); return true; } /** * 场景4-检查错误关闭订单 * * @return {@link Boolean} */ @RequestMapping("checkErrorClose") public Boolean checkErrorCloseOrder() { //把订单状态改为关闭 Order order = Order.builder().orderId(1).orderName("上级检查错误").orderStatusEnum(OrderStatusEnum.WAITING_FOR_DELIVERY).build(); OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.WAITING_FOR_DELIVERY, OrderEvent.CHECK_ERROR_CLOSE, order); System.out.println(orderStatusEnum.toString()); return true; }}
启动程序
安装UML
随便新建一个uml文件,然后将启动程序的控制台输出内容复制到uml中
最后运行下
关键词:
[ 相关文章 ]
Cola-StateMachine组件是一种轻量级的、无状态的、基于注解的状态机实
【寿险产品定价利率下调在即年金险、分红险有望接力】上海证券报记者从
以下是意华股份在北京时间6月7日11:00分盘口异动快照:6月7日,意华股
西部数据WD_BLACK官方宣布,适用于Xbox的扩展储存卡WD_BLACKC50现已推
6月7日讯,在2023年华为全球智慧金融峰会上,华为云正式推出国内唯一能
迪迩秀|各国抛售美债?美元霸权的自我拆台之谜---美国总统拜登近日签署
1、章子怡第一次执导电影。大学老师:我第一反应是她应该不会出事。我
2023年中国环塔(国际)拉力赛、2023粤港澳大湾区铁人三项赛、第八届崇
同花顺数据显示,2023年6月6日,寒锐钴业获外资卖出2 98万股,占流通盘
山东新泰:社会化服务确保“颗粒归仓”---现在收割机一上,只需要十几
想必现在有很多小伙伴对于老夫的少女心是什么意思,是男的说还是女的说
2023年中国钾肥海运进口合同达成,价格较上年下降283美元 吨:据中国无
鸵鸟蛋蒸时间约为1 5-3小时左右。因为鸵鸟蛋相对于普通的鸡蛋而言,要
1、不好会有水垢。2、最好用纯净水。本文分享完毕,希望对大家有所帮助
上证报中国证券网讯6日道琼斯指数开盘报33547 67点,微跌0 05%,标普50
“在短时间内发生这么大面积沉降,在国内外比较少见!”6月5日,在天津
美股快速拉升:美股快速拉升,纳指涨0 3%。纳斯达克中国金龙指数涨1 8%
相信目前很多小伙伴对于陆丰市教育局都比较感兴趣,那么小搜今天在网上
1、重合就是指数字或代数式一样重叠和重合差不多。2、就是用在几何里比
昨晚又去了,唱到最后曲终人散之前,剩下几个人都没精神了,只有我一个
[ 相关新闻 ]
Copyright 2015-2022 热讯医院网 版权所有 备案号:豫ICP备20005723号-6 联系邮箱:29 59 11 57 8@qq.com