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

Spring StateMachine 使用小結(jié)

 更新時間:2025年11月17日 11:08:48   作者:猩火燎猿  
Spring StateMachine是一個用于管理復(fù)雜狀態(tài)流轉(zhuǎn)的框架,本文就來介紹一下Spring StateMachine 使用,具有一定的參考價值,感興趣的可以了解一下

一、基本概念

狀態(tài)機(State Machine) 是一種行為模型,定義了一組狀態(tài)、狀態(tài)之間的轉(zhuǎn)換(事件驅(qū)動)、以及在狀態(tài)轉(zhuǎn)換時觸發(fā)的動作。Spring StateMachine 提供了強大的框架支持,幫助開發(fā)者管理和驅(qū)動復(fù)雜的狀態(tài)流。

核心要素:

  • State(狀態(tài)):對象所處的不同階段。
  • Event(事件):觸發(fā)狀態(tài)轉(zhuǎn)換的動作。
  • Transition(轉(zhuǎn)換):狀態(tài)之間的轉(zhuǎn)換過程。
  • Action(動作):狀態(tài)轉(zhuǎn)換時執(zhí)行的業(yè)務(wù)邏輯。

二、核心組件

  1. StateMachine:狀態(tài)機核心接口,負責狀態(tài)管理和事件驅(qū)動。
  2. StateMachineConfigurerAdapter:狀態(tài)機配置適配器,用戶自定義狀態(tài)、事件、轉(zhuǎn)換邏輯。
  3. StateMachineFactory:狀態(tài)機工廠,創(chuàng)建狀態(tài)機實例。
  4. Actions:狀態(tài)轉(zhuǎn)換時執(zhí)行的具體業(yè)務(wù)邏輯。
  5. Guards:轉(zhuǎn)換前的條件判斷。

三、引入依賴

<!-- Maven依賴 -->
<dependency>
    <groupId>org.springframework.statemachine</groupId>
    <artifactId>spring-statemachine-core</artifactId>
    <version>4.0.0</version>
</dependency>

四、定義狀態(tài)和事件

以訂單流程為例:

public enum OrderStates {
    CREATED, PAID, SHIPPED, COMPLETED, CANCELLED
}
 
public enum OrderEvents {
    PAY, SHIP, COMPLETE, CANCEL
}

五、配置狀態(tài)機

通過繼承 StateMachineConfigurerAdapter 進行配置:

@Configuration
@EnableStateMachine
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStates, OrderEvents> {
 
    @Override
    public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states) throws Exception {
        states
            .withStates()
            .initial(OrderStates.CREATED)
            .states(EnumSet.allOf(OrderStates.class));
    }
 
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions) throws Exception {
        transitions
            .withExternal().source(OrderStates.CREATED).target(OrderStates.PAID).event(OrderEvents.PAY)
            .and()
            .withExternal().source(OrderStates.PAID).target(OrderStates.SHIPPED).event(OrderEvents.SHIP)
            .and()
            .withExternal().source(OrderStates.SHIPPED).target(OrderStates.COMPLETED).event(OrderEvents.COMPLETE)
            .and()
            .withExternal().source(OrderStates.CREATED).target(OrderStates.CANCELLED).event(OrderEvents.CANCEL)
            .and()
            .withExternal().source(OrderStates.PAID).target(OrderStates.CANCELLED).event(OrderEvents.CANCEL);
    }
}

六、使用狀態(tài)機

注入并驅(qū)動狀態(tài)機:

@Autowired
private StateMachine<OrderStates, OrderEvents> stateMachine;
 
public void processOrder() {
    stateMachine.start();
    stateMachine.sendEvent(OrderEvents.PAY);
    stateMachine.sendEvent(OrderEvents.SHIP);
    stateMachine.sendEvent(OrderEvents.COMPLETE);
}

七、添加動作和條件

1. 動作(Action)

@Bean
public Action<OrderStates, OrderEvents> payAction() {
    return context -> {
        System.out.println("訂單已支付,執(zhí)行相關(guān)業(yè)務(wù)邏輯");
    };
}
 
@Override
public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions) throws Exception {
    transitions
        .withExternal()
        .source(OrderStates.CREATED).target(OrderStates.PAID).event(OrderEvents.PAY)
        .action(payAction())
        // 其他轉(zhuǎn)換...
}

2. 條件(Guard)

@Bean
public Guard<OrderStates, OrderEvents> payGuard() {
    return context -> {
        // 只有金額大于0才能支付
        Integer amount = (Integer) context.getMessageHeader("amount");
        return amount != null && amount > 0;
    };
}
 
@Override
public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions) throws Exception {
    transitions
        .withExternal()
        .source(OrderStates.CREATED).target(OrderStates.PAID).event(OrderEvents.PAY)
        .guard(payGuard())
        // 其他轉(zhuǎn)換...
}

八、持久化狀態(tài)機(可選)

Spring StateMachine 支持狀態(tài)持久化,可用 Redis、JPA 等存儲狀態(tài),適合分布式場景。

九、最佳實踐

  1. 合理拆分狀態(tài)與事件,避免過于復(fù)雜的狀態(tài)流。
  2. 利用動作和條件,實現(xiàn)業(yè)務(wù)與狀態(tài)解耦。
  3. 持久化狀態(tài)機,保證高可用和一致性。
  4. 結(jié)合 @WithStateMachine 注解,方便事件監(jiān)聽與回調(diào)。

十一、進階用法

1. 狀態(tài)監(jiān)聽器(StateMachineListener)

可以通過監(jiān)聽器獲取狀態(tài)變化、事件處理、異常等回調(diào):

@Component
public class OrderStateMachineListener extends StateMachineListenerAdapter<OrderStates, OrderEvents> {
    @Override
    public void stateChanged(State<OrderStates, OrderEvents> from, State<OrderStates, OrderEvents> to) {
        System.out.println("狀態(tài)從 " + (from == null ? "none" : from.getId()) + " 變?yōu)?" + to.getId());
    }
 
    @Override
    public void eventNotAccepted(Message<OrderEvents> event) {
        System.out.println("事件未被接受: " + event.getPayload());
    }
}

注冊監(jiān)聽器:

@Autowired
private StateMachine<OrderStates, OrderEvents> stateMachine;
@Autowired
private OrderStateMachineListener listener;
 
@PostConstruct
public void addListener() {
    stateMachine.addStateListener(listener);
}

2. 狀態(tài)機嵌套(子狀態(tài)機)

Spring StateMachine 支持嵌套狀態(tài)(Hierarchical States),適合復(fù)雜流程。

@Override
public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states) throws Exception {
    states
        .withStates()
        .initial(OrderStates.CREATED)
        .state(OrderStates.PAID)
        .and()
        .withStates()
            .parent(OrderStates.PAID)
            .initial(OrderStates.PAID_SUB1)
            .state(OrderStates.PAID_SUB2);
}

3. 狀態(tài)機持久化

以 Redis 為例,持久化狀態(tài)機:

@Bean
public StateMachinePersister<OrderStates, OrderEvents, String> persister(
        RedisStateMachinePersister<OrderStates, OrderEvents> persister) {
    return persister;
}
 
// 保存狀態(tài)
persister.persist(stateMachine, "orderId-123");
// 恢復(fù)狀態(tài)
persister.restore(stateMachine, "orderId-123");

4. 多實例狀態(tài)機

對于每個業(yè)務(wù)對象(如訂單),建議為每個對象創(chuàng)建獨立的狀態(tài)機實例:

@Autowired
private StateMachineFactory<OrderStates, OrderEvents> factory;
 
public void handleOrder(String orderId) {
    StateMachine<OrderStates, OrderEvents> sm = factory.getStateMachine(orderId);
    sm.start();
    sm.sendEvent(OrderEvents.PAY);
}

5. 結(jié)合Spring事件機制

可以通過監(jiān)聽 StateMachineEvent,實現(xiàn)解耦的業(yè)務(wù)響應(yīng)。

十二、常見問題

  1. 狀態(tài)未切換?

    • 檢查事件是否正確發(fā)送,狀態(tài)機是否 start(),Guard 是否返回 true。
  2. 狀態(tài)機線程安全?

    • 默認是線程不安全的,業(yè)務(wù)并發(fā)場景下請為每個業(yè)務(wù)對象創(chuàng)建獨立狀態(tài)機實例。
  3. 如何調(diào)試?

    • 打開日志:logging.level.org.springframework.statemachine=DEBUG,方便追蹤狀態(tài)流轉(zhuǎn)。
  4. 如何與數(shù)據(jù)庫結(jié)合?

    • 利用持久化接口,將狀態(tài)機狀態(tài)存入數(shù)據(jù)庫,保證分布式一致性。

十三、實戰(zhàn)建議

  • 不要把所有業(yè)務(wù)邏輯都塞到 Action,只做與狀態(tài)相關(guān)的處理,復(fù)雜邏輯建議外部調(diào)用。
  • 事件驅(qū)動:外部只需發(fā)事件,狀態(tài)機自動處理后續(xù)流轉(zhuǎn)。
  • 解耦:狀態(tài)機只關(guān)注流程和狀態(tài),業(yè)務(wù)邏輯在合適的位置實現(xiàn)。
  • 測試:多寫單元測試,覆蓋各個狀態(tài)和異常流轉(zhuǎn)。

十四、完整示例

1. 配置類

@Configuration
@EnableStateMachineFactory
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStates, OrderEvents> {
    // 狀態(tài)、事件、轉(zhuǎn)移配置同上
}

2. 業(yè)務(wù)調(diào)用

@Service
public class OrderService {
    @Autowired
    private StateMachineFactory<OrderStates, OrderEvents> factory;
 
    public void payOrder(String orderId) {
        StateMachine<OrderStates, OrderEvents> sm = factory.getStateMachine(orderId);
        sm.start();
        sm.sendEvent(OrderEvents.PAY);
        // 可持久化 sm
    }
}

3. 持久化(可選)

@Autowired
private StateMachinePersister<OrderStates, OrderEvents, String> persister;
 
public void saveState(StateMachine<OrderStates, OrderEvents> sm, String orderId) throws Exception {
    persister.persist(sm, orderId);
}
 
public void restoreState(StateMachine<OrderStates, OrderEvents> sm, String orderId) throws Exception {
    persister.restore(sm, orderId);
}

到此這篇關(guān)于Spring StateMachine 使用小結(jié)的文章就介紹到這了,更多相關(guān)Spring StateMachine 使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot 1.5.7整合Kafka-client代碼示例

    Springboot 1.5.7整合Kafka-client代碼示例

    這篇文章主要介紹了Springboot 1.5.7整合Kafka-client代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • 解決阿里代碼規(guī)范檢測中方法缺少javadoc注釋的問題

    解決阿里代碼規(guī)范檢測中方法缺少javadoc注釋的問題

    這篇文章主要介紹了解決阿里代碼規(guī)范檢測中方法缺少javadoc注釋的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Java的函數(shù)式接口@FunctionalInterface的使用說明

    Java的函數(shù)式接口@FunctionalInterface的使用說明

    這篇文章主要介紹了Java的函數(shù)式接口@FunctionalInterface的使用說明,我們常用的一些接口Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解,需要的朋友可以參考下
    2024-01-01
  • Java中FTPClient上傳中文目錄、中文文件名亂碼問題解決方法

    Java中FTPClient上傳中文目錄、中文文件名亂碼問題解決方法

    這篇文章主要介紹了Java中FTPClient上傳中文目錄、中文文件名亂碼問題解決方法,本文使用apache-commons-net工具包時遇到這個問題,解決方法很簡單,需要的朋友可以參考下
    2015-05-05
  • SSM設(shè)置歡迎頁的三種方式總結(jié)

    SSM設(shè)置歡迎頁的三種方式總結(jié)

    這篇文章主要介紹了SSM項目設(shè)置歡迎頁的三種方式:使用web.xml配置、使用SpringMVC-mvc:view-controller配置和使用SpringMVC-Controller配置,每種方式都有其適用場景、優(yōu)點和缺點,需要的朋友可以參考下
    2026-02-02
  • java jdk1.8 使用stream流進行l(wèi)ist 分組歸類操作

    java jdk1.8 使用stream流進行l(wèi)ist 分組歸類操作

    這篇文章主要介紹了java jdk1.8 使用stream流進行l(wèi)ist 分組歸類操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java面試題沖刺第二十七天--JVM2

    Java面試題沖刺第二十七天--JVM2

    這篇文章主要為大家分享了最有價值的三道關(guān)于JVM的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java內(nèi)部類和異常類的概念以及使用

    Java內(nèi)部類和異常類的概念以及使用

    這篇文章主要介紹了Java內(nèi)部類和異常類的概念以及使用,文中有非常詳細的代碼以及注釋,適合正在學習java基礎(chǔ)的同學們使用,需要的朋友可以參考下
    2021-04-04
  • Java實現(xiàn)數(shù)獨小游戲

    Java實現(xiàn)數(shù)獨小游戲

    這篇文章主要為大家詳細介紹了Java實現(xiàn)數(shù)獨小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 微服務(wù)SpringConfig配置中心詳解

    微服務(wù)SpringConfig配置中心詳解

    這篇文章主要介紹了微服務(wù)SpringConfig配置中心,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04

最新評論

板桥市| 门头沟区| 泗洪县| 张掖市| 茂名市| 襄城县| 荥阳市| 舞钢市| 栖霞市| 柘荣县| 读书| 山西省| 壤塘县| 杭锦旗| 清水县| 古交市| 额济纳旗| 海丰县| 资溪县| 蕉岭县| 恩施市| 平罗县| 满洲里市| 万山特区| 托里县| 靖宇县| 湖南省| 乐业县| 大港区| 英吉沙县| 抚远县| 连江县| 永定县| 杭锦旗| 汉中市| 湘潭市| 高淳县| 康保县| 溧阳市| 石首市| 郎溪县|