摘要:創建了后,狀態機就可以不只是傳一個,可以組合和數據內容一起發送給狀態機變化的處理類了。到這里為止,狀態機通過對象就和其他的業務代碼做到了數據連接。
在企業開發中,數據在不同的業務間傳輸是最常見的工作,所以雖然我們的主架構是用的狀態機,也就是從流程狀態的角度來看待這個項目,但在具體業務中,每個狀態的轉變中會牽涉到各類業務,這些業務有些需要收到狀態機變化的通知,需要把狀態值傳遞給業務類和業務方法,同樣的,在處理狀態變化是,也需要獲取業務數據,方便不同的業務在同一個狀態變化環節做各自的業務,下面我們就講下這個數據在spring statemachine里面的傳遞。
這次我們的順序變一下,由外部傳入一個訂單號到controller開始:
@RequestMapping("/testOrderState")
public void testOrderState(String orderId) throws Exception { StateMachinestateMachine = 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
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(Messagemessage) { System.out.println("傳遞的參數:" + message.getHeaders().get("order")); logger.info("---用戶已收貨,訂單完成---"); }
首先,receive方法的參數由之前的為空:
public void receive() {
logger.info("---用戶已收貨,訂單完成---");
}
改成了Message
另外如果我們需要傳遞多個數據對象怎么辦呢,比如我們在實際業務中,除了傳訂單數據,可能還需要把商品數據,或者支付結果數據也傳過來,那么也容易,我們還是從controller里面開始:
Message
在后面繼續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對象就和其他的業務代碼做到了數據連接。其實這個很關鍵,只有做到和其他業務的數據傳遞,才能算的上真正的可用。
下一章我們繼續講狀態機的持久化問題和怎么在非起始狀態開始創建狀態機
碼云配套代碼地址
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74981.html
摘要:講講復雜流程的需求除了上面文章里面提到的一根筋狀態機流程,實際的企業應用中狀態機的流程會更加復雜,而我們最常用到的就是。當然,里面還有很多其他的東西,大部分是處理復雜狀態機流程的,以后有機會我們再展開講。 1、講講復雜流程的需求除了上面文章里面提到的一根筋狀態機流程,實際的企業應用中狀態機的流程會更加復雜,而我們最常用到的就是choice。它類似于java的if語句,作為條件判斷的分支...
摘要:雖然多個狀態機的問題解決了,但是對于實際的企業應用而言,還是有問題。這個問題就用到了狀態機的持久化,我們下一章就談談持久化問題。 1、多個狀態機的搞法在實際的企業應用中,基本不可能只有一個狀態機流程在跑,比如訂單,肯定是很多個訂單在運行,每個訂單都有自己的訂單狀態機流程,但上一章的例子,大家可以試一下,當執行到一個狀態時,再次刷新頁面,不會有任何日志出現,當一個狀態流程執行到某個狀態,...
摘要:目前為止,我們都是從狀態流程的開始階段創建一個狀態機,然后一路走下去。然后就可以愉快的在里面看怎么用了發送事件持久化恢復狀態機后的狀態為執行完保存后,大家可以自己在客戶端查看以下,是不是有內容保存進去了。 目前為止,我們都是從狀態流程的開始階段創建一個狀態機,然后一路走下去。但在實際業務中,狀態機可能需要在某個環節停留,等待其他業務的觸發,然后再繼續下面的流程。比如訂單,可能在支付環節...
摘要:目前為止,多個狀態機和多種狀態機都可以在里面實現了,下一章我們來解決下狀態機和實際業務間的數據傳輸問題,畢竟我們不是為了讓狀態機自個獨自玩耍,和業務數據互通有無才是企業開發的正道。 在上一章的例子中,我們實現了多個狀態機并存執行,不同的訂單有各自的狀態機運行,但只有一種狀態機,這顯然不能滿足實際業務的要求,比如我就遇到了訂單流程和公文審批流程在同一個項目的情況,所以我們這一章講怎么讓多...
摘要:先來一個,它的主要作用就告訴狀態機的初始狀態應該啥樣,然后把整個狀態流程都用代碼配置出來。繼承了類,表明身份,我就是來配置狀態機的初始狀態,并描繪一下狀態流程的全過程。 上一篇說了很多廢話,這一篇就不嘮叨,先跑起來 1、來個spring boot去start.spring.io新建一個springboot的項目,雖然我對spirngboot也有不少的牢騷,但作為demo的開始,還是一個...
閱讀 2861·2021-10-14 09:50
閱讀 1218·2021-10-08 10:21
閱讀 3646·2021-10-08 10:16
閱讀 3063·2021-09-27 14:02
閱讀 3135·2021-09-23 11:21
閱讀 2109·2021-09-07 10:17
閱讀 407·2019-08-30 14:00
閱讀 2105·2019-08-29 17:26