Spring-StateMachine企业级项目应用(二)-动作和条件分支

上一节介绍了状态机的构建方式,在状态机构建中有许多的要素,比如在一个Transition节点中完成状态迁移的动作定义,前置条件的定义。

迁移动作定义Action<S, E>

  • 动作的定义实现笔者采用的JavaConfig的方式对所有需要定义的动作进行实现,具体方法如下:
/**
 * Author: lehu
 * Description: 定义订单状态机执行动作
 * Date: Create in 下午4:15 20/5/21
 */
@Slf4j
@Configuration
public class OrderStateActionConfig {

    /**
     * 异常处理Action
     *
     * @return action对象
     */
    @Bean(name = "errorHandlerAction", autowire = Autowire.BY_TYPE)
    public Action<OrderStatusEnum, OrderChangeEventEnum> errorHandlerAction() {

        return context -> {
            RuntimeException exception = (RuntimeException) context.getException();
            log.error("stateMachine execute error");
            context.getStateMachine()
                    .getExtendedState().getVariables()
                    .put(RuntimeException.class, exception);
        };
    }

    /**
     * 订单创建Action
     * 建议将数据持久化的动作都放到action中统一处理。包括动作完成后的短信触发等
     *
     * @return action对象
     */
    @Bean(name = "orderCreateAction", autowire = Autowire.BY_TYPE)
    public Action<OrderStatusEnum, OrderChangeEventEnum> orderCreateAction() {
        return context -> {
            //TODO 订单创建需要处理的相关逻辑,如短信发送等
            StatusModelDO statusModelDO = (StatusModelDO)context.getMessage().getHeaders().get(StateMachineConstants.STATE_MODEL_DTO);
            log.info("orderCreateAction:" + JSON.toJSONString(statusModelDO));
        };
    }
}
  • 将定义好的Action通过依赖注入的形式注入到订单构造器实现类里面,参与状态机的流程定义:
    /**
     * 注入状态转移动作
     */
    @Resource(name = "errorHandlerAction")
    private Action<OrderStatusEnum, OrderChangeEventEnum> errorHandlerAction;

    @Resource(name = "orderCreateAction")
    private Action<OrderStatusEnum, OrderChangeEventEnum> orderCreateAction;

条件分支的定义Guard<S, E>

  • 条件分支的定义和动作一样也使用了JavaConfig的方式进行实现:
/**
* Author: lehu
* Description:
* Date: Create in 下午4:28 20/5/21
*/
@Slf4j
@Configuration
public class OrderStateGuardConfig {

   /**
    * 是否可以创建订单
    * @return Guard
    */
   @Bean(name = "orderCreateGuard", autowire = Autowire.BY_TYPE)
   public Guard<OrderStatusEnum, OrderChangeEventEnum> orderCreateGuard() {
       return context -> {
           log.info("orderCreateGuard");
           return true;
       };
   }
}
  • 将定义好的Guard通过依赖注入的形式注入到订单构造器实现类里面,参与状态机的流程定义:
    /**
     * 注入状态分支条件
     */
    @Resource(name = "orderCreateGuard")
    private Guard<OrderStatusEnum, OrderChangeEventEnum> orderCreateGuard;

完整的节点定义

这里使用刚刚定义好的动作以及条件分支判断完成了一个Transition节点的定义

 builder.configureTransitions() 
            .withExternal()
             //当前节点状态-订单创建
            .source(OrderStatusEnum.CREATE) 
            //目标节点状态-待支付
            .target(OrderStatusEnum.WAIT_PAYMENT)
            //导致当前变化的事件,用户下单
            .event(OrderChangeEventEnum.CREATE_ORDER)
            /**
             * 执行相关动作的前置条件判断
             * orderCreateGuard为Guard<S, E>接口的实现类
             */
            .guard(orderCreateGuard)
            /**
             * 执行当前状态变更导致的业务逻辑处理,以及异常处理
             * orderCreateAction、errorHandlerAction为Action<S, E>接口的实现类
             */
            .action(orderCreateAction, errorHandlerAction) 

到这里我们已经将一个状态机的构建方式以及构建所需要的各个要素的实现介绍完成了,接下来我们将介绍如何构建一个状态机实例。

上一篇:Spring-StateMachine企业级项目应用(一)-基础理解
下一篇:Spring-StateMachine企业级项目应用(三)-状态机构造

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容