squirrel-foundation-demo

池麒
2023-12-01

一个简单的squirrel-foundation-demo
利用状态机模拟一个订单的支付过程。
squirrel-foundation没有任何严重的依赖关系,因此基本上它应该是高度可嵌入的。squirrel-foundation没有整合spring框架,所以首先要用spring集成squirrel-foundation。
spring集成squirrel-foundation
(1).通过Spring创建StateMachineBuilder实例(单例);

(2).业务函数中通过(1)的StateMachineBuilder实例创建StateMachine实例,并向StateMachine暴露SpringApplicationContext,以便于StateMachine通过ApplicationContext获取数据层的对象。

public class AbstractStateMachineEngine <T extends UntypedStateMachine> implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    protected UntypedStateMachineBuilder stateMachineBuilder = null;

    @SuppressWarnings("unchecked")
    public AbstractStateMachineEngine() {
        //识别泛型参数
        Class<T> genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(),
                AbstractStateMachineEngine.class);
        stateMachineBuilder = StateMachineBuilderFactory.create(genericType, ApplicationContext.class);
    }
    //注入applicationContext,并在创建StateMachine实例时注入
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void fire(OrderEvent event, OrderContext context) {
        T stateMachine = stateMachineBuilder.newUntypedStateMachine(
                context.orderDTO.getState(),
                //暂时开启debug进行日志trace
                StateMachineConfiguration.create().enableDebugMode(true).enableAutoStart(true),
                //注入applicationContext
                applicationContext);
        stateMachine.fire(event, context);
    }
}

  •  

继承AbstractStateMachineEngine,并加入@Service注解,便可以在项目中注入。(单例)

@Service
public class OrderStateMachineEngine extends AbstractStateMachineEngine<SubmitOrderStateMachine>{

}

  •  

基于注解的方式定义状态机
@States 定义状态列表,里面可以包含多个状态
@State定义每个状态,name状态名称,entryStateInit进入状态时调用的方法,exitCallMethod 离开状态是调用的方法,initialState 为true时,为默认状态。

@States({
        @State(name = "INIT", entryCallMethod = "entryStateInit", exitCallMethod = "exitStateInit", initialState = true),
        @State(name = "WAIT_PAY", entryCallMethod = "entryStateWaitPay", exitCallMethod = "exitStateWaitPay"),
        @State(name = "WAIT_SEND", entryCallMethod = "entryStateWaitSend", exitCallMethod = "exitStateWaitSend"),
        @State(name = "PART_SEND", entryCallMethod = "entryStatePartSend", exitCallMethod = "exitStatePartSend"),
        @State(name = "WAIT_RECEIVE", entryCallMethod = "entryStateWaitReceive", exitCallMethod = "exitStateWaitReceive"),
        @State(name = "COMPLETE", entryCallMethod = "entryStateComplete", exitCallMethod = "exitStateComplete")
})
@Transitions({
        @Transit(from = "INIT", to = "WAIT_PAY", on = "SUBMIT_ORDER", callMethod = "submitOrder"),
        @Transit(from = "WAIT_PAY", to = "WAIT_SEND", on = "PAY", callMethod = "pay"),
        @Transit(from = "WAIT_SEND", to = "PART_SEND", on = "PART_SEND", callMethod = "partSend"),
        @Transit(from = "PART_SEND", to = "WAIT_RECEIVE", on = "SEND", callMethod = "send"),
        @Transit(from = "WAIT_RECEIVE", to = "COMPLETE", on = "COMPLETE", callMethod = "complete")
})
@StateMachineParameters(stateType = OrderState.class, eventType = OrderEvent.class, contextType = OrderContext.class)
public class SubmitOrderStateMachine extends AbstractStateMachine<UntypedStateMachine, Object, Object, Object> implements UntypedStateMachine {

    private OrderService orderService;
    protected ApplicationContext applicationContext;
    //定义构造函数接受ApplicationContext注入([参看New State Machine Instance](http://hekailiang.github.io/squirrel/))
    public SubmitOrderStateMachine(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        // 通过applicationContext注入orderService
          orderService = (OrderService) this.applicationContext.getBean(OrderService.class);
    }

    public void submitOrder(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        orderService.submitOrder(toState);
    }

    public void pay(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("pay");
    }

    public void partSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("partSend");
    }

    public void send(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("send");
    }

    public void complete(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("complete");
    }

    public void entryStateInit(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("entryStateInit");
    }

    public void exitStateInit(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("exitStateInit");
    }

    public void entryStateWaitPay(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("entryStateWaitPay");
    }

    public void exitStateWaitPay(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("exitStateWaitPay");
    }

    public void entryStateWaitSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("entryStateWaitSend");
    }

    public void exitStateWaitSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("exitStateWaitSend");
    }

    public void entryStatePartSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("entryStatePartSend");
    }

    public void exitStatePartSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("exitStatePartSend");
    }

    public void entryStateWaitReceive(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("entryStateWaitReceive");
    }

    public void exitStateWaitReceive(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("exitStateWaitReceive");
    }

    public void entryStateComplete(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("entryStateComplete");
    }

    public void exitStateComplete(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
        System.out.println("exitStateComplete");
    }

}

  •  

Service的实现,更新订单状态

@Service
public class OrderService {

    @Autowired
    OrderDTOMapper orderDTOMapper;

    public int submitOrder(OrderState state) {
        OrderDTO orderDTO = new OrderDTO();
        orderDTO.setState(state);
        orderDTOMapper.insert(orderDTO);
        return 1;
    }

}

  •  

mapper


@Mapper
public interface OrderDTOMapper {

    int insert(OrderDTO orderDTO);

}

  •  

Controller类测试
注入OrderStateMachineEngine ,初始化状态为INIT,通过OrderStateMachineEngine 触发SUBMIT_ORDER事件,发生状态变化,并将转换后的状态插入数据库。

@RestController
@RequestMapping(value = "/order/")
public class OrderController {

	// 注入状态机
    @Autowired
    OrderStateMachineEngine orderStateMachineEngine;


    @RequestMapping("/test")
    public void test(){
        OrderDTO orderDTO = new OrderDTO(OrderState.INIT);
        OrderContext orderContext = new OrderContext(orderDTO);
        orderStateMachineEngine.fire(OrderEvent.SUBMIT_ORDER,orderContext);

    }

}
  •  

以下是所用到的实体类定义和状态及事件
订单的实体

public class OrderDTO {

    private Integer id;

    private OrderState state;

    private Date createTime;

    private Date updateTime;

    public Integer getId() {
        return id;
    }

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

    public OrderState getState() {
        return state;
    }

    public void setState(OrderState state) {
        this.state = state;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    @Override
    public String toString() {
        return "OrderDTO{" +
                "id=" + id +
                ", state='" + state + '\'' +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                '}';
    }

    public OrderDTO(OrderState state) {
        this.state = state;
    }

    public OrderDTO() {
    }
}


  •  

定义订单的状态

public enum OrderState {

    INIT,

    WAIT_PAY,

    WAIT_SEND,

    PART_SEND,

    WAIT_RECEIVE,

    COMPLETE,

    CANCELED;

    public static OrderState getState(String state) {
        for (OrderState orderState : OrderState.values()) {
            if (orderState.name().equalsIgnoreCase(state)) {
                return orderState;
            }
        }
        return null;
    }
}
  •  

定义订单的事件

public enum OrderEvent {

    SUBMIT_ORDER,
    PAY,
    PART_SEND,
    SEND,
    COMPLETE

}

  •  

定义上下文

public class OrderContext {

    public OrderContext(OrderDTO orderDTO) {
        this.orderDTO = orderDTO;
    }

    public OrderContext() {
    }

    public OrderDTO orderDTO;

}
 类似资料: