[Spring]Spring-Statemachine 狀態機

輸入圖片說明

介紹

Spring狀態機爲程序開發員提供了傳統狀態機和Spring應用程序使用,有如下特性:安全

  1. 易於使用的狀態機的用例
  2. 層次的狀態機結構緩解複雜狀態機的配置
  3. 狀態機提供更復雜的配置狀態
  4. 使用觸發器、轉移、警衛以及動做
  5. 類型安全的配置適配器
  6. 狀態機的事件監聽器
  7. IOC將狀態機和bean整合

名詞解釋

  • State Machine
    • 將狀態結合、轉移、事件整合到一塊兒
  • State
    • 一個不變的狀態模型
    • 主要由一個事件修改實體的狀態
  • Extended State
    • 擴展狀態是一組特殊的變量保存在一個狀態機來減小所需的數據量。
  • Transition
    • 源狀態和目標狀態之間的關係,它多是複合過分的一部分,將狀態機配置從一個狀態到另外一個地方,響應狀態機的一個特定類型的事件的發生。
  • Event
    • 一個實體發送一個狀態驅動各個狀態的變化
  • Initial State
    • 狀態機特殊的開始狀態. 初始狀態標記在一個狀態或者一個區域上. 一個狀態的多個區域均可能回到初始狀態
  • End State
    • 一種最終狀態,一種特殊的狀態表示完成封閉區域,若是封閉區域直接包含在一個狀態機狀態機和其餘地區也完成了,而後它意味着整個狀態機完成。
  • History State
    • 僞狀態能夠記住它的最後活動的狀態, 存在兩種類型歷史狀態.
  • Choice State
    • 容許選擇基礎即過分, 事件標題或擴展狀態變量.
  • Fork State
    • 狀態賦予一個控制進入一個地區.
  • Join State
    • 狀態賦予一個退出控制區域.
  • Region
    • 組合狀態或者狀態機。它包含狀態和轉換.
  • Guard
    • 用一個布爾表達式來表示擴展狀態變量的價值動態評估和事件參數. 守衛條件影響的行爲狀態機經過啓用操做或轉換,只有當他們評估爲TRUE並評估爲FALSE時禁用它們.
  • Action
    • 行動是一種行爲的觸發過渡期間執行.

使用場景

  • 若是你的項目很好的使用狀態機:
    • 應用程序的結構能夠表示成狀態的一部分。
    • 你但願複雜的邏輯分割成更小的可管理的任務。
    • 應用程序已經遭受異步的併發性問題。
  • 若是你準備實現一個狀態機:
    • 使用布爾標記和枚舉模型的狀況
    • 對於某些應用程序生命週期的一部分的有效變量
    • 遍歷if/else結構設置特定標示和枚舉

例子

定義枚舉和實現

/**
* 狀態
*/
public enum Status{

    START,
    CANCEL,
    ENE;

}
/**
* 事件
*/
public enum Events {
    SAVE;
}

狀態機配置

@Configuration
@EnableStateMachine(name = "orderStateMachine")
public class TestStateMachineConfig extends EnumStateMachineConfigurerAdapter<Status, Events> {

    @Resource
    private SaveAction saveAction;

    @Override
    public void configure(StateMachineStateConfigurer<Status, Events> states)
            throws Exception {
        states
                .withStates()
                .initial(Status.START)
                .states(EnumSet.allOf(Status.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<Status, Events> transitions)
            throws Exception {
        transitions
                .withExternal()
                .source(Status.START).target(Status.END)
                .event(Events.SAVE).action(saveAction)
                ;
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<Status, Events> config)
            throws Exception {
        config
                .withConfiguration().autoStartup(true)
                .listener(listener());
    }

    @Bean
    public StateMachineListener<Status, Events> listener() {
        return new StateMachineListenerAdapter<Status, Events>() {
            @Override
            public void transition(Transition<Status, Events> transition) {
                if (transition.getTarget().getId() == Status.START) {
                    System.out.println("建立");
                    return;
                }

            }
        };
    }


}

定義Action

@Component
public class SaveAction implements Action<Status, Events>{

    @Resource
    private OrderInfoService orderInfoService;

    @Override
    public void execute(StateContext<Status, Events> context) {
        Order order  = (Order) context.getMessageHeader(OrderStatusContextKey.ORDER_ENTITY_KEY);

        orderInfoService.save(order);

    }
}

狀態機管理類

@Component
public class DefaultStateMachineManager implements InitializingBean, ApplicationContextAware {

    private static final String ORDER_STATE_MACHINE_CONFIG = "orderStateMachine";

    private ApplicationContext applicationContext;
    private StateMachine<Status, Events> orderStateMachine;
  

    @Override
    public void afterPropertiesSet() throws Exception {
        orderStateMachine = applicationContext.getBean(ORDER_STATE_MACHINE_CONFIG, StateMachine.class);
     
    }

    @Override
    public StateMachine<OrderStatus, Events> getOrderStateMachine() {
        return orderStateMachine;
    }

  

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

業務層

@Service
public class OrderBizImpl {

    @Resource
    private StateMachineManager stateMachineManager;

    @Override
    public void save(Order order) {

        if (order == null) {
            return;
        }

        StateMachine<Status, Events> orderStateMachine = stateMachineManager.getOrderStateMachine();

        Message<Events> message = MessageBuilder
                .withPayload(Events.SAVE)
                .setHeader(ORDER_ENTITY_KEY, order)
                .build();

        orderStateMachine.sendEvent(message);
    }


}
相關文章
相關標籤/搜索