10分钟带你体验 Solon 的状态机

一、介绍

Solon 状态机,称为 Solon State Machine。它是一种可以管理状态、事件之间的关系,以及他们之间的转换。这是一个专门为应用程序中的状态管理和状态转换提供支持的框架。

它简化了事物对象在不同状态下,不同事件转化的代码管理,让其代码变得更加清晰明了。

本文将介绍 Solon State Machine 状态机在 Solon 框架下的使用,10分钟带你理解并上手使用 Solon 状态机

二、状态机的核心概念

首先,我们必须要了解 Solon 状态机的几个核心概念,如下

  • 状态(State):代表着对象的当前状态
  • 事件(Event):对象状态转变是因何而改变的
  • 转换(Transition):定义了事物的状态是通过哪个事件变到了另一个状态

比如,最常见的就是订单系统,下面就简单模拟一下正常订单的状态流转:

  • 用户下单(状态为:待支付)
  • 用户支付成功(状态为:已支付待发货)
  • 仓库已发货(状态为:已发货待收货)
  • 用户成功收货(状态为:已收货)

三、代码

添加对应的 maven 依赖

xml 复制代码
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-statemachine</artifactId>
    <version>3.5.0</version>
</dependency>

对于状态,由于非常固定,我们最好是使用枚举,如下OrderStatus.java

java 复制代码
import org.noear.solon.statemachine.State;

public enum OrderStatusEnum implements State{
    WAIT_PAY, //待支付
    WAIT_DELIVER, //已支付待发货
    WAIT_RECEIVE, //已发货待收货
    RECEIVED; //已收货
}

还要定义一下事件的枚举

java 复制代码
import org.noear.solon.statemachine.Event;

public enum OrderStatusEventEnum implements Event{
    ORDER, //用户下单
    PAY, //用户支付成功
    DELIVER, //仓库已发货
    RECEIVE; //用户成功收货
}

接下来我们就能定义转换了,在 Solon 框架下,我们可以定义一个 OrderStateMachine 托管类

java 复制代码
@Managed
public class OrderStateMachine extends StateMachine<OrderStatusEnum,OrderStatusEventEnum, OrderEntity> {
    public OrderStateMachine() {
        // 待支付 -> 已支付待发货(支付成功)
        addTransition(t -> t.
                from(OrderStatusEnum.WAIT_PAY)
                .to(OrderStatusEnum.WAIT_DELIVER)
                .on(OrderStatusEventEnum.PAY)
                .then(c -> c.getPayload().setStatus(c.getTo())));

        // 已支付待发货 -> 已发货待收货(仓库已发货)
        addTransition(t -> t.
                from(OrderStatusEnum.WAIT_DELIVER)
                .to(OrderStatusEnum.WAIT_RECEIVE)
                .on(OrderStatusEventEnum.DELIVER)
                .then(c -> c.getPayload().setStatus(c.getTo())));

        // 已发货待收货 -> 已收货(用户收货)
        addTransition(t -> t.
                from(OrderStatusEnum.WAIT_RECEIVE)
                .to(OrderStatusEnum.RECEIVED)
                .on(OrderStatusEventEnum.RECEIVE)
                .then(c -> c.getPayload().setStatus(c.getTo())));
    }
}

是不是感觉还缺了什么呢,配置中还缺少一个下单事件,这没有关系,这是我们初始的一个事件,不参于配置

我们写对应的 OrderController 接口即可,这边模拟一下,创建订单进行落库

java 复制代码
@Controller
public class OrderController {
    @Mapping("/create")
    public Result<Void> create() {
        // TODO 模拟订单落库
        return Result.succeed();
    }
}

重点是在后面的,支付这一个阶段,我们应该如何接入状态机,如下

java 复制代码
@Controller
public class OrderController {
    @Inject
    private OrderStateMachine orderStatusMachine;

    @Mapping("/create")
    public Result create() {
        // TODO 模拟订单落库
        return Result.succeed();
    }

    @Post
    @Mapping("/pay")
    public Result pay() {
        // TODO 模拟订单支付
        return Result.succeed();
    }

    @Post
    @Mapping("/payNotify")
    public Result payNotify(Integer orderId) {
        // TODO 支付成功后,使用状态机

        // 模拟通过id查找一个订单对象
        OrderEntity entity = new OrderEntity(orderId, OrderStatusEnum.WAIT_PAY);

        // 使用状态机发送这个消息
        orderStatusMachine.sendEvent(OrderStatusEventEnum.PAY, EventContext.of(entity.getStatus(), entity));
        return Result.succeed();
    }
}
相关推荐
无限进步_3 分钟前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神4 分钟前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe7 分钟前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿7 分钟前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
阿维的博客日记18 分钟前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson19 分钟前
CAS的底层实现
java
九英里路31 分钟前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串
YDS82935 分钟前
大营销平台 —— 抽奖前置规则过滤
java·spring boot·ddd
仍然.39 分钟前
多线程---CAS,JUC组件和线程安全的集合类
java·开发语言
不懂的浪漫1 小时前
mqtt-plus 架构解析(五):错误处理与 ErrorAction 聚合策略
java·spring boot·后端·物联网·mqtt·架构