Spring状态机的介绍与使用

打印 上一主题 下一主题

主题 888|帖子 888|积分 2664

1.什么是Spring的状态机


  • Spring 状态机(Spring State Machine)是 Spring Framework 提供的一个模块,用于支持有限状态机(Finite State Machine,FSM)的实现。有限状态机是一个数学模型,描述了一个系统在不同状态之间的转换以及触发这些转换的事件。
  • Spring 状态机主要用于处理对象的状态变化和状态之间的转换。它提供了一种以声明性的方式定义状态和状态之间转换的机制,并能够处理各种事件触发的状态迁移。这在某些应用中非常有用,比如工作流、订单处理、游戏引擎等领域。
  • Spring StatsMachine主要涉及到两个重要的概念,一个是State(状态)、一个是Event(事件)。

2.Spring 状态机的使用


  • 场景:商城项目中对于订单状态的层层转换。
1.使用Spring状态机先引入它的Maven依赖
  1.         <dependency>
  2.             <groupId>org.springframework.statemachine</groupId>
  3.             <artifactId>spring-statemachine-starter</artifactId>
  4.             <version>2.2.0.RELEASE</version>
  5.         </dependency>
  6.         <dependency>
  7.          <groupId>org.springframework.statemachine</groupId>
  8.         <artifactId>spring-statemachine-redis</artifactId>
  9.     </dependency>               
复制代码
2.生成状态机的状态与事件:(OrderState,OrderEvents)

  • OrderState:
  1. public enum OrderState {
  2.     UNPAID,                 // 待支付
  3.     WAITING_FOR_RECEIVE,    // 待收货
  4.     DONE                    // 结束
  5. }
复制代码

  • OrderEvents
  1. public enum OrderEvents {
  2.     PAY,        // 支付
  3.     RECEIVE     // 收货
  4. }
复制代码
3.将状态与事件进行绑定:(StateMachineConfig)
  1. @Configuration
  2. @EnableStateMachine(name = "StateMachineConfig")
  3. public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<TestState, TestEvents> {
  4.     private Logger logger = LoggerFactory.getLogger(getClass());
  5.     //定义初始状态
  6.     @Override
  7.     public void configure(StateMachineStateConfigurer<TestState, TestEvents> states)
  8.             throws Exception {
  9.         states
  10.             .withStates()
  11.                 .initial(TestState.UNPAID)
  12.                 .states(EnumSet.allOf(TestState.class));
  13.     }
  14.     //状态转换过程 触发什么事件就转换为什么状态
  15.     @Override
  16.     public void configure(StateMachineTransitionConfigurer<TestState, TestEvents> transitions)
  17.             throws Exception {
  18.         transitions
  19.             .withExternal()
  20.                 .source(TestState.UNPAID).target(TestState.WAITING_FOR_RECEIVE)
  21.                 .event(TestEvents.PAY)
  22.                 .and()
  23.             .withExternal()
  24.                 .source(TestState.WAITING_FOR_RECEIVE).target(TestState.DONE)
  25.                 .event(TestEvents.RECEIVE);
  26.     }
  27. }
复制代码
4.将事件监听触发与配置类进行配置:(EventListener)
  1. @Component
  2. @WithStateMachine(name = "StateMachineConfig")
  3. public class EventListener {
  4.     private Logger logger = LoggerFactory.getLogger(getClass());
  5.     @OnTransition(target = "UNPAID")
  6.     public boolean create(Message<Order> order) {<br>     // 创建订单逻辑
  7.         logger.info("订单创建,待支付");
  8.         return true;
  9.     }
  10.     @OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
  11.     public boolean pay(Message<Order> order) {
  12.         // 支付逻辑 从redis根据order 来进行处理
  13.         logger.info("用户完成支付,待收货");
  14.         return true;
  15.     }
  16.     @OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
  17.     public boolean receive(Message<Order> order) {<br>     //从redis中根据传入的order 来查询当前订单 并业务处理
  18.         logger.info("用户已收货,订单完成");
  19.         return true;
  20.     }
  21. }
复制代码
最后测试:
  1. @SpringBootApplication
  2. public class DemoApplication implements CommandLineRunner {
  3.     public DemoApplication(StateMachine<TestState, TestEvents> stateMachine) {
  4.         this.stateMachine = stateMachine;
  5.     }
  6.     public static void main(String[] args) {
  7.         SpringApplication.run(DemoApplication.class, args);
  8.     }
  9.     private final StateMachine<TestState, TestEvents> stateMachine;
  10.     @Override
  11.     public void run(String... args) throws Exception {
  12.         Order order=new Order("测试",0);
  13.         // 使用 MessageBuilder 创建消息并设置负载和头信息
  14.         Message message = MessageBuilder
  15.                 .withPayload(TestEvents.PAY)
  16.                 .setHeader("order", order)
  17.                 .build();
  18.         // 发送消息给状态机
  19.         stateMachine.start();
  20.         stateMachine.sendEvent(message);
  21.     }
  22. }
复制代码
测试结果:

 结论:在一些工作流、订单处理的时候可以使用状态机这种设计模式,将状态和事件进行绑定,然后对状态改变进行监听,最后只需要在监听内部对业务代码进行处理。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曂沅仴駦

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表