资讯专栏INFORMATION COLUMN

spring statemachine的企业可用级开发指南5-传递参数的message

YacaToy / 387人阅读

摘要:创建了后,状态机就可以不只是传一个,可以组合和数据内容一起发送给状态机变化的处理类了。到这里为止,状态机通过对象就和其他的业务代码做到了数据连接。

在企业开发中,数据在不同的业务间传输是最常见的工作,所以虽然我们的主架构是用的状态机,也就是从流程状态的角度来看待这个项目,但在具体业务中,每个状态的转变中会牵涉到各类业务,这些业务有些需要收到状态机变化的通知,需要把状态值传递给业务类和业务方法,同样的,在处理状态变化是,也需要获取业务数据,方便不同的业务在同一个状态变化环节做各自的业务,下面我们就讲下这个数据在spring statemachine里面的传递。

这次我们的顺序变一下,由外部传入一个订单号到controller开始:

@RequestMapping("/testOrderState")

public void testOrderState(String orderId) throws Exception {

    StateMachine stateMachine = orderStateMachineBuilder.build(beanFactory);
    System.out.println(stateMachine.getId());

    // 创建流程
    stateMachine.start();

    // 触发PAY事件
    stateMachine.sendEvent(OrderEvents.PAY);

    // 触发RECEIVE事件
    Order order = new Order(orderId, "547568678", "广东省深圳市", "13435465465", "RECEIVE");
    Message message = MessageBuilder.withPayload(OrderEvents.RECEIVE).setHeader("order", order).build();
    stateMachine.sendEvent(message);

    // 获取最终状态
    System.out.println("最终状态:" + stateMachine.getState().getId());
}

controller收到request请求的参数,orderId,然后状态机依次触发事件,到触发RECEIVE事件的时候,我们新建了一个Order,并把orderId塞进去了,其实更多的情况应该是我们拿到orderId,然后查询数据库,得到order数据对象,这里为了简化代码,就新建一个啦。

然后就是真正的主角登场了,Message。它其实不是spirng statemachine专属的,它是spring里面通用的一种消息工具,看它的源代码:

package org.springframework.messaging;

public interface Message {

/**
 * Return the message payload.
 */
T getPayload();

/**
 * Return message headers for the message (never {@code null} but may be empty).
 */
MessageHeaders getHeaders();

}
它由两个部分组成,看图就知道了,和代码里面是一致的

在spring statemachine里面,我们把状态塞到message的payload里面,然后把需要传递的业务数据(例子里面就是order对象)塞到header里面。创建message用的是messagebuilder,看它的名字就知道是专门创建message的。

Message message = MessageBuilder.withPayload(OrderEvents.RECEIVE).setHeader("order", order).build();

    stateMachine.sendEvent(message);

创建了message后,状态机sendEvent就可以不只是传一个event,可以组合event(OrderEvents.RECEIVE)和数据内容(order)一起发送给状态机变化的处理类eventconfig了。让我们看eventConfig的处理:

/**

 * WAITING_FOR_RECEIVE->DONE 执行的动作
 */
@OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
public void receive(Message message) {
    System.out.println("传递的参数:" + message.getHeaders().get("order"));
    logger.info("---用户已收货,订单完成---");
}

首先,receive方法的参数由之前的为空:

public void receive() {

    logger.info("---用户已收货,订单完成---");

}
改成了Message message,这样就能从message的getHeaders里面取到传递过来的数据对象了。

另外如果我们需要传递多个数据对象怎么办呢,比如我们在实际业务中,除了传订单数据,可能还需要把商品数据,或者支付结果数据也传过来,那么也容易,我们还是从controller里面开始:

Message message = MessageBuilder.withPayload(OrderEvents.RECEIVE).setHeader("order", order).setHeader("otherobj", "otherobjvalue").build();
在后面继续setHeader就好了,然后到eventConfig里面:

System.out.println("传递的参数:" + message.getHeaders().get("order"));
System.out.println("传递的参数:" + message.getHeaders().get("otherObj"));
运行后看日志:

传递的参数:Order [id=null, userId=547568678, address=广东省深圳市, phoneNum=13435465465, state=RECEIVE]
传递的参数:otherObjValue
可知两个的数据都传递到了eventConfig里面了,这个就实现了多个数据对象的同时传递。

到这里为止,状态机通过message对象就和其他的业务代码做到了数据连接。其实这个很关键,只有做到和其他业务的数据传递,才能算的上真正的可用。

下一章我们继续讲状态机的持久化问题和怎么在非起始状态开始创建状态机

码云配套代码地址

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74981.html

相关文章

  • spring statemachine企业可用开发指南8-复杂状态机实现

    摘要:讲讲复杂流程的需求除了上面文章里面提到的一根筋状态机流程,实际的企业应用中状态机的流程会更加复杂,而我们最常用到的就是。当然,里面还有很多其他的东西,大部分是处理复杂状态机流程的,以后有机会我们再展开讲。 1、讲讲复杂流程的需求除了上面文章里面提到的一根筋状态机流程,实际的企业应用中状态机的流程会更加复杂,而我们最常用到的就是choice。它类似于java的if语句,作为条件判断的分支...

    jzzlee 评论0 收藏0
  • spring statemachine企业可用开发指南3-多个状态机共存

    摘要:虽然多个状态机的问题解决了,但是对于实际的企业应用而言,还是有问题。这个问题就用到了状态机的持久化,我们下一章就谈谈持久化问题。 1、多个状态机的搞法在实际的企业应用中,基本不可能只有一个状态机流程在跑,比如订单,肯定是很多个订单在运行,每个订单都有自己的订单状态机流程,但上一章的例子,大家可以试一下,当执行到一个状态时,再次刷新页面,不会有任何日志出现,当一个状态流程执行到某个状态,...

    zhongmeizhi 评论0 收藏0
  • spring statemachine企业可用开发指南6-持久化

    摘要:目前为止,我们都是从状态流程的开始阶段创建一个状态机,然后一路走下去。然后就可以愉快的在里面看怎么用了发送事件持久化恢复状态机后的状态为执行完保存后,大家可以自己在客户端查看以下,是不是有内容保存进去了。 目前为止,我们都是从状态流程的开始阶段创建一个状态机,然后一路走下去。但在实际业务中,状态机可能需要在某个环节停留,等待其他业务的触发,然后再继续下面的流程。比如订单,可能在支付环节...

    Jioby 评论0 收藏0
  • spring statemachine企业可用开发指南4-多种状态机共存

    摘要:目前为止,多个状态机和多种状态机都可以在里面实现了,下一章我们来解决下状态机和实际业务间的数据传输问题,毕竟我们不是为了让状态机自个独自玩耍,和业务数据互通有无才是企业开发的正道。 在上一章的例子中,我们实现了多个状态机并存执行,不同的订单有各自的状态机运行,但只有一种状态机,这显然不能满足实际业务的要求,比如我就遇到了订单流程和公文审批流程在同一个项目的情况,所以我们这一章讲怎么让多...

    boredream 评论0 收藏0
  • spring statemachine企业可用开发指南2-先跑起来

    摘要:先来一个,它的主要作用就告诉状态机的初始状态应该啥样,然后把整个状态流程都用代码配置出来。继承了类,表明身份,我就是来配置状态机的初始状态,并描绘一下状态流程的全过程。 上一篇说了很多废话,这一篇就不唠叨,先跑起来 1、来个spring boot去start.spring.io新建一个springboot的项目,虽然我对spirngboot也有不少的牢骚,但作为demo的开始,还是一个...

    lvzishen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<