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

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

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

1、問(wèn)題概述

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

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

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

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

3、配置層級(jí)狀態(tài)節(jié)點(diǎn)

在 configure(StateMachineStateConfigurer) 中,我們利用 .parent() 語(yǔ)法來(lái)編織狀態(tài)之間的樹狀層級(jí)關(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()
                //注冊(cè)最外層的頂層獨(dú)立狀態(tài)
                .initial(OrderState.PENDING_PAY) //頂層起點(diǎn):待支付
                .end(OrderState.PENDING_DELIVER) //頂層終點(diǎn):待發(fā)貨
                .state(OrderState.IN_PAYMENT)    //宏觀負(fù)狀態(tài):支付中
                .and()
            //嵌套子狀態(tài)
            .withStates()
                .parent(OrderState.IN_PAYMENT)   //指明父節(jié)點(diǎn)
                .initial(OrderState.PAY_PREPARE) //子狀態(tài)的第一個(gè)狀態(tài)
                .state(OrderState.PAY_PROCESSING);//扣款中
    }
}

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

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

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

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

我們?cè)跍y(cè)試中連續(xù)投遞事件,看看狀態(tài)機(jī)的內(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("當(dāng)前激活狀態(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("當(dāng)前激活狀態(tài): " + sm.getState().getIds()); 
    // ?? 預(yù)期輸出: [IN_PAYMENT, PAY_PREPARE] (父子同時(shí)激活)
    // 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("當(dāng)前激活狀態(tài): " + sm.getState().getIds()); 
    // ?? 預(yù)期輸出: [IN_PAYMENT, PAY_PROCESSING] (父狀態(tài)不變,子狀態(tài)向前)
    // 4. 支付成功 -> 強(qiáng)行打破嵌套,融合成頂層終態(tài)
    sm.sendEvent(Mono.just(MessageBuilder.withPayload(OrderEvent.PAY_SUCCESS).build())).blockLast();
    System.out.println("--- 4. 發(fā)送 PAY_SUCCESS 后 ---");
    System.out.println("當(dāng)前激活狀態(tài): " + sm.getState().getIds()); 
    // ?? 預(yù)期輸出: [PENDING_DELIVER] (子狀態(tài)全部銷毀,回歸單頂層狀態(tài))
}
--- 初始狀態(tài) ---
[PENDING_PAY]
--- 1. 點(diǎn)擊去支付后 ---
[IN_PAYMENT, PAY_PREPARE]
--- 2. 進(jìn)入銀行扣款中后 ---
[IN_PAYMENT, PAY_PROCESSING]
--- 3. 收到扣款失敗回調(diào)后 ---
[PENDING_PAY]
--- 4. 第二次嘗試,重新進(jìn)入扣款中 ---
[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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

    Java中的synchronized重量級(jí)鎖解析

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

    自定義SpringBoot的白標(biāo)錯(cuò)誤頁(yè)面的操作方法

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

    java中LinkedBlockingQueue與ArrayBlockingQueue的異同

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

    利用SpringBoot和LiteFlow解鎖復(fù)雜流程

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

    自治县| 从化市| 秦安县| 台北市| 阿坝县| 东台市| 灵武市| 莲花县| 北碚区| 安顺市| 图片| 南宁市| 宁夏| 吉水县| 海兴县| 常州市| 西平县| 高要市| 牟定县| 镇巴县| 德令哈市| 宣化县| 黑河市| 大悟县| 惠安县| 蓝山县| 沅陵县| 玉田县| 台湾省| 安福县| 黄平县| 璧山县| 阳山县| 巴彦县| 开鲁县| 秀山| 蒲城县| 怀化市| 和政县| 廊坊市| 扶余县|