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

栏目: Java · 发布时间: 5年前

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

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

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

@RequestMapping("/testOrderState")

public void testOrderState(String orderId) throws Exception {

    StateMachine<OrderStates, OrderEvents> 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<OrderEvents> 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<T> {

/**
 * 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<OrderEvents> 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<OrderEvents> message) {
    System.out.println("传递的参数:" + message.getHeaders().get("order"));
    logger.info("---用户已收货,订单完成---");
}

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

public void receive() {

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

}

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

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

Message<OrderEvents> 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对象就和其他的业务代码做到了数据连接。其实这个很关键,只有做到和其他业务的数据传递,才能算的上真正的可用。

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

码云配套代码地址


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML 5实战

HTML 5实战

陶国荣 / 机械工业出版社 / 2011-11 / 59.00元

陶国荣编著的《HTML5实战》是一本系统而全面的HTML 5教程,根据HTML 5标准的最新草案,系统地对HTML 5的所有重要知识点进行了全面的讲解。在写作方式上,本书以一种开创性的方式使理论与实践达到极好的平衡,不仅对理论知识进行了清晰而透彻的阐述,而且根据读者理解这些知识的需要,精心设计了106个完整(每个案例分为功能描述、实现代码、效果展示和代码分析4个部分)的实战案例,旨在帮助读者通过实......一起来看看 《HTML 5实战》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具