基于Spring-statemachine的有限状态机(FSM)的介绍及示例

本文介绍了如何将Spring-statemachine框架集成到Springboot应用中,以一个订单状态流程为例,展示了状态机的配置、状态和事件定义、监听器的使用以及状态转移的验证。通过示例代码,解释了如何处理状态转移和持久化操作。
摘要由CSDN通过智能技术生成

前言

本文主要介绍一下状态机以及相关的一些概念。结合一个简单的订单状态流程,示例怎样在Springboot中集成Spring-statemachine。

有限状态机(Finite-state machine)

有限状态机(英语:finite-state machine,缩写:FSM),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。应用FSM模型可以帮助对象生命周期的状态的顺序以及导致状态变化的事件进行管理。将状态和事件控制从不同的业务Service方法的if else中抽离出来。FSM的应用范围很广,对于有复杂状态流,扩展性要求比较高的场景都可以使用该模型。下面是状态机模型中的4个要素,即现态、条件、动作、次态。

  • 现态:是指当前所处的状态。
  • 条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
  • 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
  • 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

如下图示例:有限的状态集是“opend”以及“closed”。如果“现态”是“opend”,当“条件”为“Close”时,执行的“动作”是“close door”,次态则为“closed”。状态机逻辑执行完毕后“closed”则变成了“现态”。

有限状态机

所以FSM的执行逻辑可以理解为下图,即FSM的下一个状态和输出是由输入和当前状态决定的:

FSM的执行逻辑

集成Spring-statemachine框架到Springboot应用

对于使用Java语言的应用来说,可以选择的集成框架也比较多。如squirrel-foundationspring-statemachinestateless4j 。squirrel-foundation,stateless4j相对spring-statemachine更加轻量级。感兴趣的可以去看下这两个项目的源码。

Spring官网项目的QuickStart中没有对于持久化模型的举例。所以本文以一个持久化的流程——一个简单的示例订单流程进行举例。示例代码中,持久化框架使用了hibernate-jpa,请求的示范例子用了spring-web,spring-webmvc的Rest api。基于JDK8。Spring statemachine版本:1.2.7,SpringBoot 版本:1.5.3。

配置

gradle 配置的版本
dependencies {
    compile 'org.springframework.statemachine:spring-statemachine-core:1.2.7.RELEASE'
}  

示例-订单的状态流程

如下图,本文示例一个简单的订单流程。
订单状态图

订单状态模型

状态枚举类OrderStatus

public enum OrderStatus {

    // 待支付,待发货,待收货,订单结束
    WAIT_PAYMENT, WAIT_DELIVER, WAIT_RECEIVE, FINISH;
}

事件枚举类OrderStatusChangeEvent:

public enum OrderStatusChangeEvent {

    // 支付,发货,确认收货
    PAYED, DELIVERY, RECEIVED
}

订单Entity Order:

@Entity
@Table(name = "order_test")
public class Order {
   

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @NotNull
    @Column(name = "order_id")
    private Integer orderId;

    @NotNull
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "status")
    private OrderStatus status;


    public Order() {
    }

    public Order(Integer orderId, OrderStatus status) {
        this.orderId = orderId;
        this.status = status;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getOrderId
  • 18
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值