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

Spring Statemachine 狀態(tài)機(jī)詳解

 更新時(shí)間:2025年09月11日 10:52:03   作者:csdn_tom_168  
SpringStatemachine是Spring應(yīng)用中的狀態(tài)機(jī)框架,支持復(fù)雜狀態(tài)轉(zhuǎn)換,適用于訂單系統(tǒng)等場(chǎng)景,核心概念包括狀態(tài)、事件、轉(zhuǎn)換,提供守衛(wèi)、動(dòng)作、并行處理等高級(jí)功能,并支持持久化與可視化,本文給大家介紹Spring Statemachine的相關(guān)知識(shí),感興趣的朋友一起看看吧

Spring Statemachine 詳解

Spring Statemachine 是一個(gè)強(qiáng)大的狀態(tài)機(jī)框架,用于在 Spring 應(yīng)用中實(shí)現(xiàn)復(fù)雜的狀態(tài)轉(zhuǎn)換邏輯。它特別適合管理具有多種狀態(tài)和轉(zhuǎn)換的業(yè)務(wù)流程,如訂單系統(tǒng)、工作流引擎、設(shè)備控制等。

一、核心概念

1. 狀態(tài)機(jī)基本元素

  • 狀態(tài)(State):系統(tǒng)所處的特定條件
  • 事件(Event):觸發(fā)狀態(tài)轉(zhuǎn)換的動(dòng)作
  • 轉(zhuǎn)換(Transition):狀態(tài)之間的遷移
  • 守衛(wèi)(Guard):轉(zhuǎn)換的條件判斷
  • 動(dòng)作(Action):狀態(tài)轉(zhuǎn)換時(shí)執(zhí)行的業(yè)務(wù)邏輯

2. 狀態(tài)類型

  • 初始狀態(tài)(Initial State):狀態(tài)機(jī)的起點(diǎn)
  • 結(jié)束狀態(tài)(End State):狀態(tài)機(jī)的終點(diǎn)
  • 普通狀態(tài)(Normal State):常規(guī)狀態(tài)
  • 選擇狀態(tài)(Choice State):基于條件的分支
  • 叉狀態(tài)(Fork State):并行執(zhí)行分支
  • 連接狀態(tài)(Join State):合并并行分支
  • 歷史狀態(tài)(History State):記錄并恢復(fù)之前狀態(tài)

二、依賴配置

Maven 依賴

<dependency>
    <groupId>org.springframework.statemachine</groupId>
    <artifactId>spring-statemachine-core</artifactId>
    <version>3.2.0</version>
</dependency>

Gradle 依賴

implementation 'org.springframework.statemachine:spring-statemachine-core:3.2.0'

三、基礎(chǔ)配置

1. 定義狀態(tài)和事件枚舉

public enum States {
    SI, // 初始狀態(tài)
    S1, 
    S2,
    SF  // 最終狀態(tài)
}
public enum Events {
    E1, 
    E2
}

2. 配置狀態(tài)機(jī)

@Configuration
@EnableStateMachine
public class StateMachineConfig 
        extends EnumStateMachineConfigurerAdapter<States, Events> {
    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
            .withStates()
            .initial(States.SI)
            .states(EnumSet.allOf(States.class))
            .end(States.SF);
    }
    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions
            .withExternal()
                .source(States.SI)
                .target(States.S1)
                .event(Events.E1)
                .and()
            .withExternal()
                .source(States.S1)
                .target(States.S2)
                .event(Events.E2);
    }
}

四、高級(jí)特性

1. 守衛(wèi)(Guard)實(shí)現(xiàn)條件轉(zhuǎn)換

public class MyGuard implements Guard<States, Events> {
    @Override
    public boolean evaluate(StateContext<States, Events> context) {
        // 檢查轉(zhuǎn)換條件
        return context.getMessageHeader("key") != null;
    }
}
// 在配置中添加守衛(wèi)
transitions
    .withExternal()
        .source(States.S1)
        .target(States.S2)
        .event(Events.E2)
        .guard(new MyGuard());

2. 動(dòng)作(Action)執(zhí)行業(yè)務(wù)邏輯

public class MyAction implements Action<States, Events> {
    @Override
    public void execute(StateContext<States, Events> context) {
        // 執(zhí)行狀態(tài)轉(zhuǎn)換時(shí)的業(yè)務(wù)邏輯
        System.out.println("Transition action executed");
    }
}
// 在配置中添加動(dòng)作
transitions
    .withExternal()
        .source(States.SI)
        .target(States.S1)
        .event(Events.E1)
        .action(new MyAction());

3. 層次狀態(tài)(Hierarchical States)

@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
        throws Exception {
    states
        .withStates()
        .initial(States.SI)
        .state(States.S1)
        .and()
        .withStates()
            .parent(States.S1)
            .initial(States.S11)
            .state(States.S12);
}

4. 并行狀態(tài)(Fork/Join)

@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
        throws Exception {
    states
        .withStates()
        .initial(States.SI)
        .fork(States.SFORK)
        .join(States.SJOIN)
        .and()
        .withStates()
            .parent(States.SFORK)
            .initial(States.S1)
            .end(States.S1END)
        .and()
        .withStates()
            .parent(States.SFORK)
            .initial(States.S2)
            .end(States.S2END);
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
        throws Exception {
    transitions
        .withFork()
            .source(States.SFORK)
            .target(States.S1)
            .target(States.S2)
        .and()
        .withJoin()
            .source(States.S1END)
            .source(States.S2END)
            .target(States.SJOIN);
}

5. 狀態(tài)機(jī)監(jiān)聽(tīng)器

@Component
public class StateMachineListener 
        extends StateMachineListenerAdapter<States, Events> {
    @Override
    public void stateChanged(State<States, Events> from, State<States, Events> to) {
        System.out.println("State changed from " + from + " to " + to);
    }
    @Override
    public void eventNotAccepted(Message<Events> event) {
        System.err.println("Event not accepted: " + event.getPayload());
    }
}

五、持久化狀態(tài)機(jī)

1. 配置持久化倉(cāng)庫(kù)

@Bean
public StateMachineRuntimePersister<States, Events, String> stateMachineRuntimePersister() {
    return new JpaStateMachineRuntimePersister<>();
}

2. 啟用持久化

@Configuration
@EnableStateMachineFactory
public class PersistConfig 
        extends StateMachineConfigurerAdapter<States, Events> {
    @Autowired
    private StateMachineRuntimePersister<States, Events, String> stateMachineRuntimePersister;
    @Override
    public void configure(StateMachineConfigurationConfigurer<States, Events> config)
            throws Exception {
        config
            .withPersistence()
            .runtimePersister(stateMachineRuntimePersister);
    }
}

3. 保存和恢復(fù)狀態(tài)

// 保存狀態(tài)
stateMachinePersist.persist(stateMachine, "machineId");
// 恢復(fù)狀態(tài)
StateMachine<States, Events> stateMachine = 
    stateMachineFactory.getStateMachine("machineId");
stateMachinePersist.restore(stateMachine, "machineId");

六、狀態(tài)機(jī)可視化

1. 導(dǎo)出UML狀態(tài)圖

UmlStateMachineModelProducer modelProducer = new UmlStateMachineModelProducer();
Model model = modelProducer.produce(stateMachine.getStateMachineModel());
UmlStateMachineModelConverter converter = new UmlStateMachineModelConverter();
String uml = converter.convertToString(model);
System.out.println(uml);

2. 生成PlantUML圖

@startuml
[*] --> SI
SI --> S1 : E1
S1 --> S2 : E2
S2 --> SF : E3
SF --> [*]
@enduml

七、完整示例:訂單狀態(tài)機(jī)

1. 定義狀態(tài)和事件

public enum OrderStates {
    CREATED,        // 訂單創(chuàng)建
    PAYMENT_PENDING, // 待支付
    PAYMENT_RECEIVED,// 已支付
    PROCESSING,     // 處理中
    SHIPPED,        // 已發(fā)貨
    DELIVERED,      // 已送達(dá)
    CANCELLED,      // 已取消
    RETURNED        // 已退貨
}
public enum OrderEvents {
    INITIATE_PAYMENT,   // 發(fā)起支付
    PAYMENT_SUCCESS,    // 支付成功
    PAYMENT_FAILED,     // 支付失敗
    PROCESS_ORDER,      // 處理訂單
    SHIP_ORDER,         // 發(fā)貨
    DELIVER_ORDER,      // 送達(dá)
    CANCEL_ORDER,       // 取消訂單
    RETURN_ORDER        // 退貨
}

2. 配置狀態(tài)機(jī)

@Configuration
@EnableStateMachineFactory
public class OrderStateMachineConfig 
        extends EnumStateMachineConfigurerAdapter<OrderStates, OrderEvents> {
    @Override
    public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states)
            throws Exception {
        states
            .withStates()
            .initial(OrderStates.CREATED)
            .state(OrderStates.PAYMENT_PENDING)
            .state(OrderStates.PAYMENT_RECEIVED)
            .state(OrderStates.PROCESSING)
            .state(OrderStates.SHIPPED)
            .state(OrderStates.DELIVERED)
            .end(OrderStates.CANCELLED)
            .end(OrderStates.RETURNED);
    }
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions)
            throws Exception {
        transitions
            // 從創(chuàng)建到待支付
            .withExternal()
                .source(OrderStates.CREATED)
                .target(OrderStates.PAYMENT_PENDING)
                .event(OrderEvents.INITIATE_PAYMENT)
                .and()
            // 支付成功
            .withExternal()
                .source(OrderStates.PAYMENT_PENDING)
                .target(OrderStates.PAYMENT_RECEIVED)
                .event(OrderEvents.PAYMENT_SUCCESS)
                .and()
            // 支付失敗
            .withExternal()
                .source(OrderStates.PAYMENT_PENDING)
                .target(OrderStates.CANCELLED)
                .event(OrderEvents.PAYMENT_FAILED)
                .and()
            // 開(kāi)始處理訂單
            .withExternal()
                .source(OrderStates.PAYMENT_RECEIVED)
                .target(OrderStates.PROCESSING)
                .event(OrderEvents.PROCESS_ORDER)
                .and()
            // 發(fā)貨
            .withExternal()
                .source(OrderStates.PROCESSING)
                .target(OrderStates.SHIPPED)
                .event(OrderEvents.SHIP_ORDER)
                .and()
            // 送達(dá)
            .withExternal()
                .source(OrderStates.SHIPPED)
                .target(OrderStates.DELIVERED)
                .event(OrderEvents.DELIVER_ORDER)
                .and()
            // 取消訂單(在特定狀態(tài)下)
            .withExternal()
                .source(OrderStates.CREATED)
                .target(OrderStates.CANCELLED)
                .event(OrderEvents.CANCEL_ORDER)
                .and()
            .withExternal()
                .source(OrderStates.PAYMENT_PENDING)
                .target(OrderStates.CANCELLED)
                .event(OrderEvents.CANCEL_ORDER)
                .and()
            // 退貨
            .withExternal()
                .source(OrderStates.DELIVERED)
                .target(OrderStates.RETURNED)
                .event(OrderEvents.RETURN_ORDER);
    }
}

3. 使用狀態(tài)機(jī)服務(wù)

@Service
public class OrderService {
    @Autowired
    private StateMachineFactory<OrderStates, OrderEvents> factory;
    private final Map<Long, StateMachine<OrderStates, OrderEvents>> machines = 
        new ConcurrentHashMap<>();
    public void createOrder(Long orderId) {
        StateMachine<OrderStates, OrderEvents> sm = buildStateMachine(orderId);
        sm.sendEvent(OrderEvents.INITIATE_PAYMENT);
    }
    public void processPayment(Long orderId, boolean success) {
        StateMachine<OrderStates, OrderEvents> sm = machines.get(orderId);
        if (sm != null) {
            sm.sendEvent(success ? 
                OrderEvents.PAYMENT_SUCCESS : 
                OrderEvents.PAYMENT_FAILED);
        }
    }
    public void shipOrder(Long orderId) {
        StateMachine<OrderStates, OrderEvents> sm = machines.get(orderId);
        if (sm != null && sm.getState().getId() == OrderStates.PROCESSING) {
            sm.sendEvent(OrderEvents.SHIP_ORDER);
        }
    }
    private StateMachine<OrderStates, OrderEvents> buildStateMachine(Long orderId) {
        StateMachine<OrderStates, OrderEvents> sm = factory.getStateMachine();
        sm.start();
        machines.put(orderId, sm);
        return sm;
    }
}

八、最佳實(shí)踐

1. 狀態(tài)機(jī)設(shè)計(jì)原則

  • 保持狀態(tài)簡(jiǎn)單:每個(gè)狀態(tài)應(yīng)有明確的含義
  • 限制狀態(tài)數(shù)量:避免狀態(tài)爆炸(State Explosion)
  • 使用層次狀態(tài):管理復(fù)雜狀態(tài)關(guān)系
  • 合理使用守衛(wèi):確保轉(zhuǎn)換條件清晰
  • 分離業(yè)務(wù)邏輯:動(dòng)作應(yīng)調(diào)用服務(wù)而非包含復(fù)雜邏輯

2. 性能優(yōu)化

  • 重用狀態(tài)機(jī)實(shí)例:避免頻繁創(chuàng)建
  • 異步事件處理:使用sendEvent(Message)異步接口
  • 合理持久化:只在必要時(shí)持久化狀態(tài)
  • 緩存守衛(wèi)結(jié)果:避免重復(fù)計(jì)算

3. 錯(cuò)誤處理

@Component
public class ErrorStateMachineListener 
        extends StateMachineListenerAdapter<OrderStates, OrderEvents> {
    @Override
    public void stateMachineError(
            StateMachine<OrderStates, OrderEvents> stateMachine, 
            Exception exception) {
        // 記錄錯(cuò)誤并處理
        System.err.println("State machine error: " + exception.getMessage());
        stateMachine.stop();
    }
    @Override
    public void eventNotAccepted(Message<OrderEvents> event) {
        // 處理不被接受的事件
        System.err.println("Event not accepted: " + event.getPayload());
    }
}

九、測(cè)試狀態(tài)機(jī)

JUnit 測(cè)試示例

@SpringBootTest
public class OrderStateMachineTest {
    @Autowired
    private StateMachineFactory<OrderStates, OrderEvents> factory;
    @Test
    public void testOrderFlow() {
        StateMachine<OrderStates, OrderEvents> sm = factory.getStateMachine();
        sm.start();
        // 初始狀態(tài)應(yīng)為CREATED
        assertEquals(OrderStates.CREATED, sm.getState().getId());
        // 發(fā)起支付
        sm.sendEvent(OrderEvents.INITIATE_PAYMENT);
        assertEquals(OrderStates.PAYMENT_PENDING, sm.getState().getId());
        // 支付成功
        sm.sendEvent(OrderEvents.PAYMENT_SUCCESS);
        assertEquals(OrderStates.PAYMENT_RECEIVED, sm.getState().getId());
        // 處理訂單
        sm.sendEvent(OrderEvents.PROCESS_ORDER);
        assertEquals(OrderStates.PROCESSING, sm.getState().getId());
        // 發(fā)貨
        sm.sendEvent(OrderEvents.SHIP_ORDER);
        assertEquals(OrderStates.SHIPPED, sm.getState().getId());
        // 送達(dá)
        sm.sendEvent(OrderEvents.DELIVER_ORDER);
        assertEquals(OrderStates.DELIVERED, sm.getState().getId());
    }
}

十、常見(jiàn)問(wèn)題解決

1. 事件未被處理

  • 檢查狀態(tài):確保當(dāng)前狀態(tài)支持該事件
  • 驗(yàn)證守衛(wèi):檢查守衛(wèi)條件是否滿足
  • 查看日志:?jiǎn)⒂肈EBUG日志查看狀態(tài)機(jī)內(nèi)部處理

2. 狀態(tài)機(jī)不啟動(dòng)

  • 檢查配置:確保@EnableStateMachine@EnableStateMachineFactory已啟用
  • 手動(dòng)啟動(dòng):調(diào)用stateMachine.start()
  • 驗(yàn)證依賴:確保所有必需依賴已正確配置

3. 并發(fā)問(wèn)題

  • 使用同步:對(duì)狀態(tài)機(jī)操作加鎖
  • 消息隊(duì)列:使用消息隊(duì)列順序處理事件
  • 狀態(tài)機(jī)池:創(chuàng)建狀態(tài)機(jī)實(shí)例池

4. 持久化失敗

  • 檢查序列化:確保狀態(tài)和事件可序列化
  • 數(shù)據(jù)庫(kù)配置:驗(yàn)證持久化倉(cāng)庫(kù)配置正確
  • 事務(wù)管理:確保在事務(wù)邊界內(nèi)操作狀態(tài)機(jī)

Spring Statemachine 提供了強(qiáng)大的狀態(tài)管理能力,特別適合處理復(fù)雜的業(yè)務(wù)流程。通過(guò)合理設(shè)計(jì)狀態(tài)模型、轉(zhuǎn)換規(guī)則和業(yè)務(wù)動(dòng)作,可以構(gòu)建出高度可維護(hù)和可擴(kuò)展的狀態(tài)驅(qū)動(dòng)應(yīng)用。

到此這篇關(guān)于Spring Statemachine 狀態(tài)機(jī)詳解的文章就介紹到這了,更多相關(guān)Spring Statemachine 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ 歸并排序(merge sort)案例詳解

    C++ 歸并排序(merge sort)案例詳解

    這篇文章主要介紹了C++ 歸并排序(merge sort)案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • SpringBoot實(shí)現(xiàn)多文件上傳的詳細(xì)示例代碼

    SpringBoot實(shí)現(xiàn)多文件上傳的詳細(xì)示例代碼

    文件上傳中并沒(méi)有什么太多的知識(shí)點(diǎn),下面這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)多文件上傳的詳細(xì)示例,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • 在Java8中使用StreamAPI的實(shí)際應(yīng)用

    在Java8中使用StreamAPI的實(shí)際應(yīng)用

    本文深入探討StreamAPI的核心概念、使用場(chǎng)景以及實(shí)際應(yīng)用,幫助你在日常開(kāi)發(fā)中更好地利用這一強(qiáng)大特性,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • MyBatis的CRUD中的不同參數(shù)綁定查詢實(shí)現(xiàn)

    MyBatis的CRUD中的不同參數(shù)綁定查詢實(shí)現(xiàn)

    本文主要介紹了MyBatis的CRUD中的不同參數(shù)綁定查詢實(shí)現(xiàn),主要包括單個(gè)參數(shù)傳遞綁定,序號(hào)參數(shù)傳遞綁定,注解參數(shù)傳遞綁定,pojo(對(duì)象)參數(shù)傳遞綁定,map參數(shù)傳遞綁定這幾種類型,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Java設(shè)計(jì)模式之代理模式與@Async異步注解失效的解決

    Java設(shè)計(jì)模式之代理模式與@Async異步注解失效的解決

    代理模式是Java常見(jiàn)的設(shè)計(jì)模式之一。所謂代理模式是指客戶端并不直接調(diào)用實(shí)際的對(duì)象,而是通過(guò)調(diào)用代理,來(lái)間接的調(diào)用實(shí)際的對(duì)象
    2022-07-07
  • Java8新特性之JavaFX 8_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java8新特性之JavaFX 8_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java8新特性之JavaFX 8的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-06-06
  • springboot項(xiàng)目配置多數(shù)據(jù)庫(kù)連接的示例詳解

    springboot項(xiàng)目配置多數(shù)據(jù)庫(kù)連接的示例詳解

    這篇文章主要介紹了springboot項(xiàng)目配置多數(shù)據(jù)庫(kù)連接的示例,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • Java Yml格式轉(zhuǎn)換為Properties問(wèn)題

    Java Yml格式轉(zhuǎn)換為Properties問(wèn)題

    本文介紹了作者編寫(xiě)一個(gè)Java工具類來(lái)解決在線YAML到Properties轉(zhuǎn)換時(shí)屬性內(nèi)容遺漏的問(wèn)題,通過(guò)遍歷YAML文件的樹(shù)結(jié)構(gòu),作者成功實(shí)現(xiàn)了屬性的完整轉(zhuǎn)換,總結(jié)指出,該工具類適用于多種數(shù)據(jù)類型,并且代碼簡(jiǎn)潔易懂
    2024-12-12
  • java 中用split分割字符串,最后的空格等不被拆分的方法

    java 中用split分割字符串,最后的空格等不被拆分的方法

    下面小編就為大家?guī)?lái)一篇java 中用split分割字符串,最后的空格等不被拆分的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • eclipse中自動(dòng)生成javadoc文檔的方法

    eclipse中自動(dòng)生成javadoc文檔的方法

    這篇文章主要介紹了eclipse中自動(dòng)生成javadoc文檔的方法,是實(shí)用eclipse開(kāi)發(fā)Java程序時(shí)非常實(shí)用的技巧,對(duì)于進(jìn)行Java項(xiàng)目開(kāi)發(fā)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-12-12

最新評(píng)論

福海县| 荣成市| 南华县| 方城县| 江油市| 古浪县| 乐清市| 潢川县| 马鞍山市| 新龙县| 宜宾市| 本溪| 昌吉市| 建水县| 大悟县| 阿拉善左旗| 扬中市| 康平县| 景洪市| 惠安县| 富蕴县| 南城县| 海伦市| 巴中市| 丹阳市| 锦屏县| 铜陵市| 晋州市| 汝阳县| 呼图壁县| 梅州市| SHOW| 信丰县| 大渡口区| 明溪县| 玛曲县| 义马市| 阿克苏市| 徐汇区| 鱼台县| 突泉县|