摘要:創(chuàng)建了后,狀態(tài)機(jī)就可以不只是傳一個(gè),可以組合和數(shù)據(jù)內(nèi)容一起發(fā)送給狀態(tài)機(jī)變化的處理類了。到這里為止,狀態(tài)機(jī)通過對象就和其他的業(yè)務(wù)代碼做到了數(shù)據(jù)連接。
在企業(yè)開發(fā)中,數(shù)據(jù)在不同的業(yè)務(wù)間傳輸是最常見的工作,所以雖然我們的主架構(gòu)是用的狀態(tài)機(jī),也就是從流程狀態(tài)的角度來看待這個(gè)項(xiàng)目,但在具體業(yè)務(wù)中,每個(gè)狀態(tài)的轉(zhuǎn)變中會牽涉到各類業(yè)務(wù),這些業(yè)務(wù)有些需要收到狀態(tài)機(jī)變化的通知,需要把狀態(tài)值傳遞給業(yè)務(wù)類和業(yè)務(wù)方法,同樣的,在處理狀態(tài)變化是,也需要獲取業(yè)務(wù)數(shù)據(jù),方便不同的業(yè)務(wù)在同一個(gè)狀態(tài)變化環(huán)節(jié)做各自的業(yè)務(wù),下面我們就講下這個(gè)數(shù)據(jù)在spring statemachine里面的傳遞。
這次我們的順序變一下,由外部傳入一個(gè)訂單號到controller開始:
@RequestMapping("/testOrderState")
public void testOrderState(String orderId) throws Exception { StateMachinestateMachine = orderStateMachineBuilder.build(beanFactory); System.out.println(stateMachine.getId()); // 創(chuàng)建流程 stateMachine.start(); // 觸發(fā)PAY事件 stateMachine.sendEvent(OrderEvents.PAY); // 觸發(fā)RECEIVE事件 Order order = new Order(orderId, "547568678", "廣東省深圳市", "13435465465", "RECEIVE"); Message message = MessageBuilder.withPayload(OrderEvents.RECEIVE).setHeader("order", order).build(); stateMachine.sendEvent(message); // 獲取最終狀態(tài) System.out.println("最終狀態(tài):" + stateMachine.getState().getId()); }
controller收到request請求的參數(shù),orderId,然后狀態(tài)機(jī)依次觸發(fā)事件,到觸發(fā)RECEIVE事件的時(shí)候,我們新建了一個(gè)Order,并把orderId塞進(jìn)去了,其實(shí)更多的情況應(yīng)該是我們拿到orderId,然后查詢數(shù)據(jù)庫,得到order數(shù)據(jù)對象,這里為了簡化代碼,就新建一個(gè)啦。
然后就是真正的主角登場了,Message。它其實(shí)不是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();
}
它由兩個(gè)部分組成,看圖就知道了,和代碼里面是一致的
在spring statemachine里面,我們把狀態(tài)塞到message的payload里面,然后把需要傳遞的業(yè)務(wù)數(shù)據(jù)(例子里面就是order對象)塞到header里面。創(chuàng)建message用的是messagebuilder,看它的名字就知道是專門創(chuàng)建message的。
Message
stateMachine.sendEvent(message);
創(chuàng)建了message后,狀態(tài)機(jī)sendEvent就可以不只是傳一個(gè)event,可以組合event(OrderEvents.RECEIVE)和數(shù)據(jù)內(nèi)容(order)一起發(fā)送給狀態(tài)機(jī)變化的處理類eventconfig了。讓我們看eventConfig的處理:
/**
* WAITING_FOR_RECEIVE->DONE 執(zhí)行的動作 */ @OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE") public void receive(Messagemessage) { System.out.println("傳遞的參數(shù):" + message.getHeaders().get("order")); logger.info("---用戶已收貨,訂單完成---"); }
首先,receive方法的參數(shù)由之前的為空:
public void receive() {
logger.info("---用戶已收貨,訂單完成---");
}
改成了Message
另外如果我們需要傳遞多個(gè)數(shù)據(jù)對象怎么辦呢,比如我們在實(shí)際業(yè)務(wù)中,除了傳訂單數(shù)據(jù),可能還需要把商品數(shù)據(jù),或者支付結(jié)果數(shù)據(jù)也傳過來,那么也容易,我們還是從controller里面開始:
Message
在后面繼續(xù)setHeader就好了,然后到eventConfig里面:
System.out.println("傳遞的參數(shù):" + message.getHeaders().get("order"));
System.out.println("傳遞的參數(shù):" + message.getHeaders().get("otherObj"));
運(yùn)行后看日志:
傳遞的參數(shù):Order [id=null, userId=547568678, address=廣東省深圳市, phoneNum=13435465465, state=RECEIVE]
傳遞的參數(shù):otherObjValue
可知兩個(gè)的數(shù)據(jù)都傳遞到了eventConfig里面了,這個(gè)就實(shí)現(xiàn)了多個(gè)數(shù)據(jù)對象的同時(shí)傳遞。
到這里為止,狀態(tài)機(jī)通過message對象就和其他的業(yè)務(wù)代碼做到了數(shù)據(jù)連接。其實(shí)這個(gè)很關(guān)鍵,只有做到和其他業(yè)務(wù)的數(shù)據(jù)傳遞,才能算的上真正的可用。
下一章我們繼續(xù)講狀態(tài)機(jī)的持久化問題和怎么在非起始狀態(tài)開始創(chuàng)建狀態(tài)機(jī)
碼云配套代碼地址
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74981.html
摘要:講講復(fù)雜流程的需求除了上面文章里面提到的一根筋狀態(tài)機(jī)流程,實(shí)際的企業(yè)應(yīng)用中狀態(tài)機(jī)的流程會更加復(fù)雜,而我們最常用到的就是。當(dāng)然,里面還有很多其他的東西,大部分是處理復(fù)雜狀態(tài)機(jī)流程的,以后有機(jī)會我們再展開講。 1、講講復(fù)雜流程的需求除了上面文章里面提到的一根筋狀態(tài)機(jī)流程,實(shí)際的企業(yè)應(yīng)用中狀態(tài)機(jī)的流程會更加復(fù)雜,而我們最常用到的就是choice。它類似于java的if語句,作為條件判斷的分支...
摘要:雖然多個(gè)狀態(tài)機(jī)的問題解決了,但是對于實(shí)際的企業(yè)應(yīng)用而言,還是有問題。這個(gè)問題就用到了狀態(tài)機(jī)的持久化,我們下一章就談?wù)劤志没瘑栴}。 1、多個(gè)狀態(tài)機(jī)的搞法在實(shí)際的企業(yè)應(yīng)用中,基本不可能只有一個(gè)狀態(tài)機(jī)流程在跑,比如訂單,肯定是很多個(gè)訂單在運(yùn)行,每個(gè)訂單都有自己的訂單狀態(tài)機(jī)流程,但上一章的例子,大家可以試一下,當(dāng)執(zhí)行到一個(gè)狀態(tài)時(shí),再次刷新頁面,不會有任何日志出現(xiàn),當(dāng)一個(gè)狀態(tài)流程執(zhí)行到某個(gè)狀態(tài),...
摘要:目前為止,我們都是從狀態(tài)流程的開始階段創(chuàng)建一個(gè)狀態(tài)機(jī),然后一路走下去。然后就可以愉快的在里面看怎么用了發(fā)送事件持久化恢復(fù)狀態(tài)機(jī)后的狀態(tài)為執(zhí)行完保存后,大家可以自己在客戶端查看以下,是不是有內(nèi)容保存進(jìn)去了。 目前為止,我們都是從狀態(tài)流程的開始階段創(chuàng)建一個(gè)狀態(tài)機(jī),然后一路走下去。但在實(shí)際業(yè)務(wù)中,狀態(tài)機(jī)可能需要在某個(gè)環(huán)節(jié)停留,等待其他業(yè)務(wù)的觸發(fā),然后再繼續(xù)下面的流程。比如訂單,可能在支付環(huán)節(jié)...
摘要:目前為止,多個(gè)狀態(tài)機(jī)和多種狀態(tài)機(jī)都可以在里面實(shí)現(xiàn)了,下一章我們來解決下狀態(tài)機(jī)和實(shí)際業(yè)務(wù)間的數(shù)據(jù)傳輸問題,畢竟我們不是為了讓狀態(tài)機(jī)自個(gè)獨(dú)自玩耍,和業(yè)務(wù)數(shù)據(jù)互通有無才是企業(yè)開發(fā)的正道。 在上一章的例子中,我們實(shí)現(xiàn)了多個(gè)狀態(tài)機(jī)并存執(zhí)行,不同的訂單有各自的狀態(tài)機(jī)運(yùn)行,但只有一種狀態(tài)機(jī),這顯然不能滿足實(shí)際業(yè)務(wù)的要求,比如我就遇到了訂單流程和公文審批流程在同一個(gè)項(xiàng)目的情況,所以我們這一章講怎么讓多...
摘要:先來一個(gè),它的主要作用就告訴狀態(tài)機(jī)的初始狀態(tài)應(yīng)該啥樣,然后把整個(gè)狀態(tài)流程都用代碼配置出來。繼承了類,表明身份,我就是來配置狀態(tài)機(jī)的初始狀態(tài),并描繪一下狀態(tài)流程的全過程。 上一篇說了很多廢話,這一篇就不嘮叨,先跑起來 1、來個(gè)spring boot去start.spring.io新建一個(gè)springboot的項(xiàng)目,雖然我對spirngboot也有不少的牢騷,但作為demo的開始,還是一個(gè)...
閱讀 2893·2021-10-14 09:50
閱讀 1235·2021-10-08 10:21
閱讀 3669·2021-10-08 10:16
閱讀 3073·2021-09-27 14:02
閱讀 3149·2021-09-23 11:21
閱讀 2141·2021-09-07 10:17
閱讀 417·2019-08-30 14:00
閱讀 2126·2019-08-29 17:26