最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring StateMachine嵌套狀態(tài)流轉(zhuǎn)

 更新時間:2026年05月23日 09:10:56   作者:吳聲子夜歌  
文章介紹了SpringStatemachine中嵌套狀態(tài)的概念、配置方法及流轉(zhuǎn)路由,嵌套狀態(tài)用于表達“狀態(tài)內(nèi)的狀態(tài)”,樹狀結(jié)構(gòu)清晰,通過.parent()配置父子關(guān)系,withExternal和withLocal分別實現(xiàn)跨級/流轉(zhuǎn)和內(nèi)部切換,測試時通過連續(xù)投遞事件,驗證狀態(tài)機狀態(tài)集合展現(xiàn)嵌套層次

1、問題概述

在 Spring StateMachine 中,嵌套狀態(tài)(Substates / Hierarchical States)是指在一個父狀態(tài)(Parent State)內(nèi)部,包含了一組子狀態(tài)(Child States)。這種設(shè)計非常適合用來表達“狀態(tài)中的狀態(tài)”,能夠?qū)碗s的業(yè)務邏輯按層級進行拆分。

在嵌套狀態(tài)中,狀態(tài)流轉(zhuǎn)遵循一個核心原則:如果狀態(tài)機當前處于某個子狀態(tài),那么它必然也同時處于該子狀態(tài)的父狀態(tài)。

假設(shè)訂單業(yè)務中有如下狀態(tài):

  • PENDING_PAY,頂層狀態(tài):待支付(初始狀態(tài))
  • IN_PAYMENT,父狀態(tài):支付中
    • PAY_PREPARE,子狀態(tài):支付準備中
    • PAY_PROCESSING,子狀態(tài):扣款中
  • PENDING_DELIVER,結(jié)束狀態(tài):待發(fā)貨

2、定義狀態(tài)與事件枚舉

//訂單狀態(tài)枚舉
public enum OrderState {
    PENDING_PAY,        // 頂層狀態(tài):待支付(初始狀態(tài))
    IN_PAYMENT,         // 父狀態(tài):支付中
    // 以下為 IN_PAYMENT 的內(nèi)部子狀態(tài)
    PAY_PREPARE,        // 子狀態(tài):支付準備中
    PAY_PROCESSING,     // 子狀態(tài):扣款中
    PENDING_DELIVER     // 結(jié)束狀態(tài):待發(fā)貨
}
//訂單事件枚舉
public enum OrderEvent {
    GO_PAY,             // 外部事件:去支付(待支付 -> 支付中)
    BANK_CONNECT,       // 內(nèi)部事件:連接渠道(支付準備中 -> 扣款中)
    PAY_SUCCESS,        // 業(yè)務結(jié)果事件:扣款成功(從扣款中跳出 -> 待發(fā)貨)
    PAY_FAIL            // 業(yè)務結(jié)果事件:扣款失?。◤目劭钪刑?-> 回到待支付)
}

3、配置層級狀態(tài)節(jié)點

在 configure(StateMachineStateConfigurer) 中,我們利用 .parent() 語法來編織狀態(tài)之間的樹狀層級關(guān)系。

@Configuration
@EnableStateMachineFactory(name = "paymentStateMachineFactory")
public class PaymentStateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {
    @Override
    public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
        states
            .withStates()
                //注冊最外層的頂層獨立狀態(tài)
                .initial(OrderState.PENDING_PAY) //頂層起點:待支付
                .end(OrderState.PENDING_DELIVER) //頂層終點:待發(fā)貨
                .state(OrderState.IN_PAYMENT)    //宏觀負狀態(tài):支付中
                .and()
            //嵌套子狀態(tài)
            .withStates()
                .parent(OrderState.IN_PAYMENT)   //指明父節(jié)點
                .initial(OrderState.PAY_PREPARE) //子狀態(tài)的第一個狀態(tài)
                .state(OrderState.PAY_PROCESSING);//扣款中
    }
}

4、配置層級流轉(zhuǎn)路由 rules

在配置流轉(zhuǎn)時,Spring StateMachine 的嵌套路由支持兩種經(jīng)典的流轉(zhuǎn)模式:

  • 外部流轉(zhuǎn)(withExternal):導致狀態(tài)發(fā)生宏觀層級跨越的跳轉(zhuǎn)(比如跳入/跳出父狀態(tài))。
  • 局部流轉(zhuǎn)(withLocal):在父狀態(tài)的樹內(nèi)部進行安全的子狀態(tài)切換,不會觸發(fā)父狀態(tài)的 onExit 或 onEntry 動作。
@Override
public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
    transitions
        // 1. 待支付 -> 跳入父狀態(tài)(支付中)
        // 此時狀態(tài)機激活集合變?yōu)椋篬IN_PAYMENT, PAY_PREPARE]
        .withExternal()
            .source(OrderState.PENDING_PAY).target(OrderState.IN_PAYMENT)
            .event(OrderEvent.GO_PAY)
            .and()
        // 2. 父狀態(tài)內(nèi)部流轉(zhuǎn):支付準備中 -> 扣款中
        // 此時狀態(tài)機激活集合變?yōu)椋篬IN_PAYMENT, PAY_PROCESSING]
        .withExternal()
            .source(OrderState.PAY_PREPARE).target(OrderState.PAY_PROCESSING)
            .event(OrderEvent.BANK_CONNECT)
            .and()
        // 3. 【核心流轉(zhuǎn)一】:扣款成功,打破父狀態(tài),流轉(zhuǎn)到頂層的“待發(fā)貨”
        // 狀態(tài)機將徹底銷毀內(nèi)部的所有子狀態(tài)指針
        .withExternal()
            .source(OrderState.IN_PAYMENT).target(OrderState.PENDING_DELIVER)
            .event(OrderEvent.PAY_SUCCESS)
            .and()
        // 4. 【核心流轉(zhuǎn)二】:扣款失敗,打破父狀態(tài),無條件滾回到頂層的“待支付”
        // 狀態(tài)機同樣會銷毀內(nèi)部指針,讓訂單恢復到最初可以重新發(fā)起支付的狀態(tài)
        .withExternal()
            .source(OrderState.IN_PAYMENT).target(OrderState.PENDING_PAY)
            .event(OrderEvent.PAY_FAIL);
}

5、測試調(diào)用與狀態(tài)打印

我們在測試中連續(xù)投遞事件,看看狀態(tài)機的內(nèi)存激活狀態(tài)集合(sm.getState().getIds())是如何展現(xiàn)嵌套層次的。

public void testHierarchicalStates() {
    StateMachine<OrderState, OrderEvent> sm = factory.getStateMachine("order_999");
    sm.startReactively().block();
    System.out.println("--- 1. 初始化 ---");
    System.out.println("當前激活狀態(tài): " + sm.getState().getIds()); // [PENDING_ORDER]
    // 2. 去支付 -> 激活嵌套
    sm.sendEvent(Mono.just(MessageBuilder.withPayload(OrderEvent.GO_PAY).build())).blockLast();
    System.out.println("--- 2. 發(fā)送 GO_PAY 后 ---");
    System.out.println("當前激活狀態(tài): " + sm.getState().getIds()); 
    // ?? 預期輸出: [IN_PAYMENT, PAY_PREPARE] (父子同時激活)
    // 3. 連接銀行 -> 子狀態(tài)流轉(zhuǎn)
    sm.sendEvent(Mono.just(MessageBuilder.withPayload(OrderEvent.BANK_CONNECT).build())).blockLast();
    System.out.println("--- 3. 發(fā)送 BANK_CONNECT 后 ---");
    System.out.println("當前激活狀態(tài): " + sm.getState().getIds()); 
    // ?? 預期輸出: [IN_PAYMENT, PAY_PROCESSING] (父狀態(tài)不變,子狀態(tài)向前)
    // 4. 支付成功 -> 強行打破嵌套,融合成頂層終態(tài)
    sm.sendEvent(Mono.just(MessageBuilder.withPayload(OrderEvent.PAY_SUCCESS).build())).blockLast();
    System.out.println("--- 4. 發(fā)送 PAY_SUCCESS 后 ---");
    System.out.println("當前激活狀態(tài): " + sm.getState().getIds()); 
    // ?? 預期輸出: [PENDING_DELIVER] (子狀態(tài)全部銷毀,回歸單頂層狀態(tài))
}
--- 初始狀態(tài) ---
[PENDING_PAY]
--- 1. 點擊去支付后 ---
[IN_PAYMENT, PAY_PREPARE]
--- 2. 進入銀行扣款中后 ---
[IN_PAYMENT, PAY_PROCESSING]
--- 3. 收到扣款失敗回調(diào)后 ---
[PENDING_PAY]
--- 4. 第二次嘗試,重新進入扣款中 ---
[IN_PAYMENT, PAY_PROCESSING]
--- 5. 收到扣款成功回調(diào)后 ---
[PENDING_DELIVER]

到此這篇關(guān)于Spring StateMachine嵌套狀態(tài)流轉(zhuǎn)的文章就介紹到這了,更多相關(guān)Spring StateMachine嵌套狀態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mongo分布式鎖Java實現(xiàn)方法(推薦)

    mongo分布式鎖Java實現(xiàn)方法(推薦)

    下面小編就為大家?guī)硪黄猰ongo分布式鎖Java實現(xiàn)方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 探討Java 將Markdown文件轉(zhuǎn)換為Word和PDF文檔

    探討Java 將Markdown文件轉(zhuǎn)換為Word和PDF文檔

    這篇文章主要介紹了Java 將Markdown文件轉(zhuǎn)換為Word和PDF文檔,本文通過分步指南及代碼示例展示了如何將 Markdown 文件轉(zhuǎn)換為 Word 文檔和 PDF 文件,需要的朋友可以參考下
    2024-07-07
  • 關(guān)于Java中Object類的幾個方法示例

    關(guān)于Java中Object類的幾個方法示例

    這篇文章主要給大家介紹了關(guān)于Java中Object類的幾個方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-05-05
  • 基于CXF搭建webService的實例講解

    基于CXF搭建webService的實例講解

    下面小編就為大家?guī)硪黄贑XF搭建webService的實例講解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 教你如何輕松學會Java快慢指針法

    教你如何輕松學會Java快慢指針法

    要想把搬磚的效率提高,我們肯定是逃不掉數(shù)據(jù)結(jié)構(gòu)和算法知識的,這不,可愛的小編今天就和大家一起學習來了,今天給大家分享的是快慢指針,那啥是快慢指針呢,文中有非常詳細的解釋,需要的朋友可以參考下
    2021-06-06
  • SpringBoot中的統(tǒng)一異常處理詳細解析

    SpringBoot中的統(tǒng)一異常處理詳細解析

    這篇文章主要介紹了SpringBoot中的統(tǒng)一異常處理詳細解析,該注解可以把異常處理器應用到所有控制器,而不是單個控制器,借助該注解,我們可以實現(xiàn):在獨立的某個地方,比如單獨一個類,定義一套對各種異常的處理機制,需要的朋友可以參考下
    2024-01-01
  • Java中的synchronized重量級鎖解析

    Java中的synchronized重量級鎖解析

    這篇文章主要介紹了Java中的synchronized重量級鎖解析,內(nèi)核需要去申請這個互斥量,必須要進入內(nèi)核態(tài),也就是這里需要用戶態(tài),內(nèi)核態(tài)的切換,狀態(tài)的切換,開銷是比較大的,這就是重型鎖的一個弊端,需要的朋友可以參考下
    2024-01-01
  • 自定義SpringBoot的白標錯誤頁面的操作方法

    自定義SpringBoot的白標錯誤頁面的操作方法

    Spring Boot的白標錯誤頁面是在應用程序出現(xiàn)錯誤時(如404或500 HTTP狀態(tài)碼)自動生成的默認錯誤頁面,下面小編給大家分享如何自定義SpringBoot的白標錯誤頁面,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • java中LinkedBlockingQueue與ArrayBlockingQueue的異同

    java中LinkedBlockingQueue與ArrayBlockingQueue的異同

    這篇文章主要介紹了java中LinkedBlockingQueue與ArrayBlockingQueue的異同,需要的朋友可以參考下
    2016-08-08
  • 利用SpringBoot和LiteFlow解鎖復雜流程

    利用SpringBoot和LiteFlow解鎖復雜流程

    隨著業(yè)務的復雜化,企業(yè)需要更加高效、便捷地管理自己的業(yè)務流程,這就需要借助一些流程引擎實現(xiàn),今天,我們就來介紹一種基于Java語言開發(fā)的輕量級工作流引擎——LiteFlow,以及如何在Spring Boot框架中集成它,從而提高企業(yè)的工作效率和開發(fā)效率
    2023-06-06

最新評論

崇州市| 雅安市| 八宿县| 文安县| 桂东县| 南昌市| 灌阳县| 繁峙县| 常州市| 剑阁县| 南郑县| 绥化市| 蒙山县| 庐江县| 边坝县| 上思县| 静乐县| 萨嘎县| 神池县| 句容市| 香港| 涞水县| 玛曲县| 民丰县| 措勤县| 彭泽县| 长沙市| 双城市| 新津县| 玉门市| 横峰县| 马公市| 乐昌市| 敖汉旗| 怀集县| 苗栗市| 鹿邑县| 金塔县| 修水县| 铜陵市| 师宗县|