
image.png
介紹
Spring狀態(tài)機(jī)為程序開(kāi)發(fā)員提供了傳統(tǒng)狀態(tài)機(jī)和Spring應(yīng)用程序使用,有以下特性:
* 易于使用的狀態(tài)機(jī)的用例
* 層次的狀態(tài)機(jī)結(jié)構(gòu)緩解復(fù)雜狀態(tài)機(jī)的配置
* 狀態(tài)機(jī)提供更復(fù)雜的配置狀態(tài)
* 使用觸發(fā)器、轉(zhuǎn)移、警衛(wèi)以及動(dòng)作
* 類型安全的配置適配器
* 狀態(tài)機(jī)的事件監(jiān)聽(tīng)器
* IOC將狀態(tài)機(jī)和bean整合
名詞解釋
- State Machine
- 將狀態(tài)結(jié)合、轉(zhuǎn)移、事件整合到一起
- State
- 一個(gè)不變的狀態(tài)模型
- 主要由一個(gè)事件修改實(shí)體的狀態(tài)
- Extended State
- 擴(kuò)展?fàn)顟B(tài)是一組特殊的變量保存在一個(gè)狀態(tài)機(jī)來(lái)減少所需的數(shù)據(jù)量。
- Transition
- 源狀態(tài)和目標(biāo)狀態(tài)之間的關(guān)系,它可能是復(fù)合過(guò)度的一部分,將狀態(tài)機(jī)配置從一個(gè)狀態(tài)到另一個(gè)地方,響應(yīng)狀態(tài)機(jī)的一個(gè)特定類型的事件的發(fā)生。
- Event
- 一個(gè)實(shí)體發(fā)送一個(gè)狀態(tài)驅(qū)動(dòng)各個(gè)狀態(tài)的變化
- Initial State
- 狀態(tài)機(jī)特殊的開(kāi)始狀態(tài). 初始狀態(tài)標(biāo)記在一個(gè)狀態(tài)或者一個(gè)區(qū)域上. 一個(gè)狀態(tài)的多個(gè)區(qū)域都可能回到初始狀態(tài)
- End State
- 一種最終狀態(tài),一種特殊的狀態(tài)表示完成封閉區(qū)域,如果封閉區(qū)域直接包含在一個(gè)狀態(tài)機(jī)狀態(tài)機(jī)和其他地區(qū)也完成了,然后它意味著整個(gè)狀態(tài)機(jī)完成。
- History State
- 偽狀態(tài)可以記住它的最后活動(dòng)的狀態(tài), 存在兩種類型歷史狀態(tài).
- Choice State
- 允許選擇基礎(chǔ)即過(guò)度, 事件標(biāo)題或擴(kuò)展?fàn)顟B(tài)變量.
- Fork State
- 狀態(tài)賦予一個(gè)控制進(jìn)入一個(gè)地區(qū).
- Join State
- 狀態(tài)賦予一個(gè)退出控制區(qū)域.
- Region
- 組合狀態(tài)或者狀態(tài)機(jī)。它包含狀態(tài)和轉(zhuǎn)換.
- Guard
- 用一個(gè)布爾表達(dá)式來(lái)表示擴(kuò)展?fàn)顟B(tài)變量的價(jià)值動(dòng)態(tài)評(píng)估和事件參數(shù). 守衛(wèi)條件影響的行為狀態(tài)機(jī)通過(guò)啟用操作或轉(zhuǎn)換,只有當(dāng)他們?cè)u(píng)估為TRUE并評(píng)估為FALSE時(shí)禁用它們.
- Action
- 行動(dòng)是一種行為的觸發(fā)過(guò)渡期間執(zhí)行.
使用場(chǎng)景
- 如果你的項(xiàng)目很好的使用狀態(tài)機(jī):
- 應(yīng)用程序的結(jié)構(gòu)可以表示成狀態(tài)的一部分。
- 你希望復(fù)雜的邏輯分割成更小的可管理的任務(wù)。
- 應(yīng)用程序已經(jīng)遭受異步的并發(fā)性問(wèn)題。
- 如果你準(zhǔn)備實(shí)現(xiàn)一個(gè)狀態(tài)機(jī):
- 使用布爾標(biāo)記和枚舉模型的情況
- 對(duì)于某些應(yīng)用程序生命周期的一部分的有效變量
- 遍歷if/else結(jié)構(gòu)設(shè)置特定標(biāo)示和枚舉
例子
定義枚舉和實(shí)現(xiàn)
/**
* 狀態(tài)
*/
public enum Status{
START,
CANCEL,
ENE;
}
/**
* 事件
*/
public enum Events {
SAVE;
}
狀態(tài)機(jī)配置
@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("訂單創(chuàng)建,待支付");
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);
}
}
狀態(tài)機(jī)管理類
@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;
}
}
業(yè)務(wù)層
@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);
}
}