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

Spring State Machine

Spring State Machine

创建 Spring Boot 项目并添加必要依赖
pom.xml 中引入 spring-statemachine-core

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

定义状态机状态与事件
使用枚举明确业务状态和触发事件:

public enum States {UNPAID,                 // 待支付WAITING_FOR_RECEIVE,    // 待收货DONE                    // 结束
}
public enum Events {PAY,        // 支付RECEIVE     // 收货
}

配置状态机逻辑
通过 @EnableStateMachine 注解激活状态机,配置初始状态和转移规则:

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;import java.util.EnumSet;@Configuration
@EnableStateMachine
@Slf4j
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<States, Events> {@Overridepublic void configure(StateMachineStateConfigurer<States, Events> states)throws Exception {states.withStates().initial(States.UNPAID).states(EnumSet.allOf(States.class));}@Overridepublic void configure(StateMachineTransitionConfigurer<States, Events> transitions)throws Exception {transitions.withExternal().source(States.UNPAID).target(States.WAITING_FOR_RECEIVE).event(Events.PAY).and().withExternal().source(States.WAITING_FOR_RECEIVE).target(States.DONE).event(Events.RECEIVE);}
}

这段代码定义了一个 Spring State Machine 的配置类,用于设置状态机的状态和转移逻辑。它继承了 EnumStateMachineConfigurerAdapter<States, Events>,这是一个便利类,让我们使用枚举轻松定义状态机。下面是对这段代码的详细解释:

用到的类和接口
EnumStateMachineConfigurerAdapter:
这个类是 Spring State Machine 提供的一个适配器类,简化了使用枚举来配置状态机的过程。通过继承这个类,可以利用其提供的默认方法来方便地设置状态和转移。
代码解析
1.configure 方法 (定义状态)

@Override
public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception {states.withStates().initial(States.UNPAID).states(EnumSet.allOf(States.class));
}

withStates():

开始配置状态。
initial(States.UNPAID):

定义状态机的初始状态为 UNPAID。状态机在启动后默认处于这个状态。
states(EnumSet.allOf(States.class)):

定义状态机所管理的所有可能状态。此处使用 EnumSet.allOf() 来获取 States 枚举中定义的所有状态,这意味着状态机将支持 UNPAID, WAITING_FOR_RECEIVE, 和 DONE 三种状态。

2.configure 方法 (定义状态转移)

@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {transitions.withExternal().source(States.UNPAID).target(States.WAITING_FOR_RECEIVE).event(Events.PAY).and().withExternal().source(States.WAITING_FOR_RECEIVE).target(States.DONE).event(Events.RECEIVE);
}
  • withExternal():
    • 定义一个外部状态转换。这是状态机中从一个状态显式转换到另一个状态的基本方式。
      source(States.UNPAID).target(States.WAITING_FOR_RECEIVE).event(Events.PAY):

定义当 PAY 事件发生时,状态从 UNPAID 转换到 WAITING_FOR_RECEIVE。这代表支付操作成功后的状态变化。
and():

连接多个状态转换配置。这里用于配置一个新的状态转换。
source(States.WAITING_FOR_RECEIVE).target(States.DONE).event(Events.RECEIVE):

定义当 RECEIVE 事件发生时,状态从 WAITING_FOR_RECEIVE 转换到 DONE。这表示收货操作成功后的状态变化,订单流程完成。

通过 CommandLineRunner 自动触发状态变更:

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {@Autowiredprivate StateMachine<States, Events> stateMachine;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Overridepublic void run(String... args) {stateMachine.start();stateMachine.sendEvent(Events.PAY);stateMachine.sendEvent(Events.RECEIVE);}
}

监听状态变更事件
通过 @OnTransition 注解实现状态变更时的业务逻辑:

import lombok.extern.slf4j.Slf4j;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
@WithStateMachine
@Slf4j
public class EventConfig {@OnTransition(target = "UNPAID")public void create() {log.info("订单创建,待支付");}@OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")public void pay() {log.info("用户完成支付,待收货");}@OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")public void receive() {log.info("用户已收货,订单完成");}
}
http://www.dtcms.com/a/271243.html

相关文章:

  • git上传大文件启用LFS git报错 the remote end hung up unexpectedly
  • 数学建模:非线性规划:二次规划问题
  • 项目管理进阶——解读智能制造项目PMO规划与项目管理方案【附全文阅读】
  • 软件测试报告第三方是什么?软件测试报告都包含啥?
  • 理解死锁:场景、实例与预防策略
  • JavaScript数组方法——梳理和考点
  • 20-C#构造函数--虚方法
  • 深度学习11(调参设参+批标准化)
  • tomcat设置预防host头攻击
  • 使用octomap将pcd点云地图转化为八叉树地图和占据栅格地图
  • MCP快速入门—快速构建自己的服务器
  • 龙虎榜——20250709
  • OpenAI 推出其 AI 代理框架的四项关键更新
  • Python数据分析案例|从模拟数据到可视化:零售门店客流量差异分析全流程
  • 拼多多正在错失即时零售?
  • C++智能指针与Qt内存管理详解
  • RESTful接口设计规范详解
  • SAP采购管理系统替代选谁?8Manage SRM全面优势测评与深度对比
  • 码云创建分支
  • 网络请求与现实生活:用办理业务类比理解HTTP通信
  • ubuntu环境下调试 RT-Thread
  • 降AI工具有哪些推荐?降AI率网站的选择与使用指南
  • 人工智能-基础篇-27-模型上下文协议--MCP到底怎么理解?对比HTTP的区别?
  • SDR(软件定义无线电)与软件定义声学系统详解
  • ECR仓库CloudFormation模板完整指南
  • 第1章 Excel界面环境与基础操作指南
  • 精准医疗,AR 锚定球囊扩张导管为健康护航​
  • 微信小程序控制空调之微信小程序篇
  • 机器学习(西瓜书) 第四章 决策树
  • 【论文阅读】AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking