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

Java中的状态机实现:使用Spring State Machine管理复杂状态流转

在软件开发中,我们经常会遇到需要处理各种状态以及状态之间转换的场景。这些状态转换有时会变得非常复杂,特别是当涉及到多个状态,并且每个状态都有多个可能的触发事件导致不同的状态变化时。手动编写这样的逻辑不仅容易出错,而且难以维护。这时,引入状态机的概念可以帮助我们更清晰地管理这些状态及其转换。本文将探讨如何利用Spring State Machine来实现这样一个状态机,并通过一个实际的业务场景来展示其实现过程。

业务场景 - 订单处理流程

假设我们在开发一个电商平台的订单处理系统。从用户下单到最终订单完成,订单的状态需要经历以下几个阶段:

  • 待支付(ORDER_PLACED):订单创建后,等待用户支付。

  • 已支付(PAID):用户已经完成了支付。

  • 已发货(SHIPPED):商家已经发货。

  • 已完成(COMPLETED):用户确认收货。

  • 已取消(CANCELLED):订单被取消。

在这个过程中,我们需要定义每个状态之间的合法转换,并且为某些状态转换添加额外的逻辑,例如,在订单从“待支付”转变为“已支付”时,我们需要检查支付信息是否正确。

使用Spring State Machine实现状态机

Spring State Machine是Spring Framework的一部分,提供了一个简单的方式来实现状态机。它支持有限状态机(FSM),并提供了许多特性来简化状态机的配置和使用。

步骤 1: 添加依赖

首先,我们需要在项目中添加Spring State Machine的依赖。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖:

xml

深色版本

<dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-core</artifactId><version>3.0.0</version>
</dependency>

步骤 2: 定义状态与转换

接下来,定义订单处理流程中的所有状态,并设置状态之间的转换规则。

java

深色版本

@Configuration
@EnableStateMachineFactory
public class OrderStateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {@Overridepublic void configure(StateMachineConfigurationConfigurer<OrderState, OrderEvent> config) throws Exception {config.withConfiguration().autoStartup(true);}@Overridepublic void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {states.withStates().initial(OrderState.ORDER_PLACED).states(EnumSet.allOf(OrderState.class));}@Overridepublic void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {transitions.withExternal().source(OrderState.ORDER_PLACED).target(OrderState.PAID).event(OrderEvent.PAYMENT_RECEIVED).and().withExternal().source(OrderState.PAID).target(OrderState.SHIPPED).event(OrderEvent.SHIPMENT_REQUESTED).and().withExternal().source(OrderState.SHIPPED).target(OrderState.COMPLETED).event(OrderEvent.DELIVERY_CONFIRMED).and().withExternal().source(OrderState.ORDER_PLACED).target(OrderState.CANCELLED).event(OrderEvent.CANCELLATION_REQUESTED).and().withExternal().source(OrderState.PAID).target(OrderState.CANCELLED).event(OrderEvent.CANCELLATION_REQUESTED);}
}

步骤 3: 触发状态转换

在业务逻辑中,当某个条件满足时,可以触发状态转换。例如,在处理支付成功的事件时,可以通过如下方式触发状态转换:

java

深色版本

@Autowired
private StateMachine<OrderState, OrderEvent> stateMachine;public void handlePaymentReceived() {stateMachine.sendEvent(OrderEvent.PAYMENT_RECEIVED);
}

步骤 4: 监听状态变化

最后,我们可以添加监听器来监听状态的变化,并执行相应的操作。例如,在订单状态从“已支付”变为“已发货”时,我们可以发送一条通知给用户。

java

深色版本

@Bean
public StateMachineListener<OrderState, OrderEvent> listener() {return new StateMachineListenerAdapter<OrderState, OrderEvent>() {@Overridepublic void stateChanged(State<OrderState, OrderEvent> from, State<OrderState, OrderEvent> to) {if (to.getId().equals(OrderState.SHIPPED)) {// 发送通知给用户}}};
}@Override
public void configure(StateMachineListenersConfigurer<OrderState, OrderEvent> listeners) throws Exception {listeners.withListeners().listener(listener());
}

以上就是使用Spring State Machine实现状态机的一个基本过程。通过这种方式,我们可以更加清晰地管理和控制应用程序中的状态转换逻辑。

相关文章:

Java中的状态机实现:使用Spring State Machine管理复杂状态流转

在软件开发中&#xff0c;我们经常会遇到需要处理各种状态以及状态之间转换的场景。这些状态转换有时会变得非常复杂&#xff0c;特别是当涉及到多个状态&#xff0c;并且每个状态都有多个可能的触发事件导致不同的状态变化时。手动编写这样的逻辑不仅容易出错&#xff0c;而且…...

[Notes] Computer Network - Overwiew

What is the Internet? The Internet is a global network of interconnected computers that communicate using standard protocols (rules). It’s not a single entity but a network of networks that allows millions of devices worldwide to exchange data. In simp…...

MyBatisPlus——学习笔记

MyBatisPlus 一、导入依赖 <!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- MySql --><de…...

运维自动化shell脚本总结

运维自动化是提升IT管理效率的关键&#xff0c;使用Shell脚本可以有效地实现许多日常任务的自动化。以下是一些常见的Shell脚本应用及其总结&#xff0c;涵盖基本概念、实用示例和最佳实践。 1. Shell脚本基础 1.1 Shell脚本定义 Shell脚本是一系列命令的集合&#xff0c;通…...

前端学习第三天笔记 JavaScript JavaScript的引入 数据类型 运算符 条件语句 字符串

这里写自定义目录标题 JavaScriptJavaScript引入到文件嵌入到HTML文件中引入本地独立js文件引入网络来源文件 JavaScript的注释方式嵌入在HTML文件中的注释JavaScript的输出方式数据类型原始类型&#xff08;基础类型&#xff09;合成类型&#xff08;复合类型&#xff09; 运算…...

C++教程一口气讲完!(万字讲解)( ̄y▽ ̄)╭ Ohohoho... 下

C 常量 常量是固定值&#xff0c;在程序执行期间不会改变。这些固定的值&#xff0c;又叫做字面量。 常量可以是任何的基本数据类型&#xff0c;可分为整型数字、浮点数字、字符、字符串和布尔值。 常量就像是常规的变量&#xff0c;只不过常量的值在定义后不能进行修改。 …...

unity软件安装教程

目录 一、Unity Hub的安装 二、Unity Hub的基础设置 语言切换 安装默认路径 安装unity编辑器和visual Studio 申请许可证 创建新项目 Unity和Visual Studio进行绑定 一、Unity Hub的安装 打开浏览器输入以下网址&#xff1a;unity.cn&#xff0c;打开unity官网 点击下载&#x…...

[大语言模型-论文精读] 更大且更可指导的语言模型变得不那么可靠

[大语言模型-论文精读] 更大且更可指导的语言模型变得不那么可靠 目录 文章目录 [大语言模型-论文精读] 更大且更可指导的语言模型变得不那么可靠目录0. 摘要1. 核心内容3. 创新点4. 算法模型5. 实验效果6. 重要数据与实验结论7. 推荐阅读指数&#xff1a;8. 推荐理由 后记 论文…...

云手机可以解决TikTok运营的哪些问题?

随着社交媒体的飞速发展&#xff0c;TikTok迅速崛起&#xff0c;成为个人和企业进行品牌宣传和内容创作的首选平台。然而&#xff0c;在运营TikTok账号的过程中&#xff0c;不少用户会遇到各种问题。本文将详细阐述云手机如何帮助解决这些问题。 1. 多账号管理的高效便捷 通过云…...

Redis基础三(redis的高级配置)

Redis进阶配置 一、Redis持久化操作 ​ 持久化就是把内存的数据写到磁盘中去&#xff0c;防止服务宕机了内存数据丢失。&#xff08;Redis 数据都放在内存中。如果机器挂掉&#xff0c;内存的数据就不存在。所以需要做持久化&#xff0c;将内存中的数据保存在磁盘&#xff0c…...

Telnet、SSH、RDP和VNC

Telnet、SSH、RDP和VNC都是远程访问和管理的协议或工具&#xff0c;它们各自具有不同的特点和适用场景。 一、基本概念与用途 Telnet 定义&#xff1a;一种基于命令行界面的远程管理协议&#xff0c;允许用户通过网络远程访问和管理计算机。用途&#xff1a;主要用于远程登录和…...

FiBiNET模型实现推荐算法

1. 项目简介 A031-FiBiNET模型项目是一个基于深度学习的推荐系统算法实现&#xff0c;旨在提升推荐系统的性能和精度。该项目的背景源于当今互联网平台中&#xff0c;推荐算法在电商、社交、内容分发等领域的广泛应用。推荐系统通过分析用户的历史行为和兴趣偏好&#xff0c;预…...

影刀RPA:Excel内容填充指令

1.实战目标 本次主要介绍影刀RPA如何操作内容相关的填充与替换指令。主要包含以下 这些指令在数据处理方面有着重要的作用&#xff0c;可以对数据做运算&#xff0c;填充&#xff0c;替换&#xff0c;实现数据格式统一&#xff0c;便于最终的数据分析。在操作的过程中&#xf…...

Threejs创建正多边体

上一章节实现了球体的绘制&#xff0c;这节来绘制多面体&#xff0c;包括正多面体&#xff0c;平面中&#xff0c;每条边一样长组成的图形叫正多边形&#xff0c;这里每个面一样&#xff0c;叫正多面体。如上文一样&#xff0c;先要创建出基础的组件&#xff0c;包括场景&#…...

链表——单链表

题目描述 实现一个单链表&#xff0c;链表初始为空&#xff0c;支持三种操作&#xff1a; (1) 向链表头插入一个数&#xff1b; (2) 删除第 k 个插入的数后面的数&#xff1b; (3) 在第 k 个插入的数后插入一个数 现在要对该链表进行 M 次操作&#xff0c;进行完所有操作后&am…...

【YOLO学习】YOLOv5口罩检测实战

文章目录 1. 环境配置2. 下载代码3. 安装库3.1 安装pytorch3.2 安装其他库 4. 测试5. 数据标注6. 模型训练7. 界面可视化 1. 环境配置 1. 先参考其他文章安装 Anaconda 或者 Miniconda&#xff0c;我安装的是 Miniconda。 2. 更换国内源&#xff0c;以加快速度 。可以参考下面这…...

场景题1-设计redis的key和value的原则

在设计 Redis 的 key 和 value 时&#xff0c;遵循一些最佳实践和设计原则可以确保系统的性能、可扩展性和易维护性。以下是设计 Redis key 和 value 时的常见原则&#xff1a; 1.RedisKey的设计原则 1.1.简短有意义 1&#xff09;Redis 是内存数据库&#xff0c;key 越短&am…...

Shell-使用函数

在 Shell 脚本中&#xff0c;函数是由一段代码定义的&#xff0c;可以被重复调用。Shell 函数的定义和调用相对简单&#xff0c;并且它支持参数传递和返回值。错误处理在 Shell 中也非常重要&#xff0c;通常通过检查返回的状态码来判断是否有错误发生。 1.Shell 函数的定义和…...

Git介绍--github/gitee/gitlab使用

一、Git的介绍 1.1、学习Git的原因&#xff1a;资源管理 1.2、SCM软件的介绍 软件配置管理(SCM)是指通过执行版本控制、变更控制的规程&#xff0c;以及使用合适的配置管理软件来保证所有配置项的完整性和可跟踪性。配置管理是对工作成果的一种有效保护。 二、版本控制软件 …...

【ubuntu】【VirtualBox】VirtualBox无法加载USB移动设备的解决方法(支持U盘启动盘)

TOC 提示&#xff1a;测试可用 一、安装VirtualBox VirtualBox-7.1.2-164945-Win。 下载路径。 Download_Old_Builds_7_0 – Oracle VirtualBox 二、安装Oracle_VirtualBox_Extension_Pack-7.1.2 下载路径见上文。 三、安装增强功能 四、挂载USB 4.1 设置USB协议 4.2 挂…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞&#xff0c;需构建多层防御体系&#xff0c;结合技术验证、存储隔离与权限控制&#xff1a; &#x1f512; 一、基础防护层 前端校验&#xff08;仅辅助&#xff09; 通过JavaScript限制文件后缀名&#xff08;白名单&#xff09;和大小&#xff0c;提…...