本篇內容主要講解“Spring中StateMachine狀態機的機制原理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Spring中StateMachine狀態機的機制原理”吧!
前言
Spring StateMachine 讓狀態機結構更加層次化,可以幫助開發者簡化狀態機的開發過程。
之前,我們使用二維數組實現狀態機機制,現在,我們來用 Spring StateMachine 進行改造。
環境依賴
修改 POM 文件,添加 spring-statemachine-core 依賴。
<dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-core</artifactId> <version>1.2.0.RELEASE</version> </dependency>
狀態和事件
現在,我以用戶注冊為案例,來講解狀態和事件之間的狀態機機制。
狀態枚舉
注冊有哪些狀態呢,我們來想想,應該有4個狀態:未連接、已連接、注冊中、已注冊。
public enum RegStatusEnum {
// 未連接
UNCONNECTED,
// 已連接
CONNECTED,
// 注冊中
REGISTERING,
// 已注冊
REGISTERED;
}事件枚舉
相對應的,存在幾個核心事件:連接、注冊、注冊成功、注冊失敗、注銷。
public enum RegEventEnum {
// 連接
CONNECT,
// 注冊
REGISTER,
// 注冊成功
REGISTER_SUCCESS,
// 注冊失敗
REGISTER_FAILED,
// 注銷
UN_REGISTER;
}狀態機配置
@Configuration
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<RegStatusEnum, RegEventEnum> {
}@EnableStateMachine注解,標識啟用 Spring StateMachine 狀態機功能。
初始化狀態機狀態
我們需要初始化狀態機的狀態。
@Override
public void configure(StateMachineStateConfigurer<RegStatusEnum, RegEventEnum> states) throws Exception {
states.withStates()
// 定義初始狀態
.initial(RegStatusEnum.UNCONNECTED)
// 定義狀態機狀態
.states(EnumSet.allOf(RegStatusEnum.class));
}其中,initial(RegStatusEnum.UNCONNECTED) 定義了初始狀態是未連接狀態。states(EnumSet.allOf(RegStatusEnum.class)) 定義了定義狀態機中存在的所有狀態。
初始化狀態遷移事件
我們需要初始化當前狀態機有哪些狀態事件。
@Override
public void configure(StateMachineTransitionConfigurer<RegStatusEnum, RegEventEnum> transitions)
throws Exception {
transitions
// 1.連接事件
// 未連接 -> 已連接
.withExternal()
.source(RegStatusEnum.UNCONNECTED)
.target(RegStatusEnum.CONNECTED)
.event(RegEventEnum.CONNECT)
.and()
// 2.注冊事件
// 已連接 -> 注冊中
.withExternal()
.source(RegStatusEnum.CONNECTED)
.target(RegStatusEnum.REGISTERING)
.event(RegEventEnum.REGISTER)
.and()
// 3.注冊成功事件
// 注冊中 -> 已注冊
.withExternal()
.source(RegStatusEnum.REGISTERING)
.target(RegStatusEnum.REGISTERED)
.event(RegEventEnum.REGISTER_SUCCESS)
.and()
// 5.注銷事件
// 已連接 -> 未連接
.withExternal()
.source(RegStatusEnum.CONNECTED)
.target(RegStatusEnum.UNCONNECTED)
.event(RegEventEnum.UN_REGISTER)
.and()
// 注冊中 -> 未連接
.withExternal()
.source(RegStatusEnum.REGISTERING)
.target(RegStatusEnum.UNCONNECTED)
.event(RegEventEnum.UN_REGISTER)
.and()
// 已注冊 -> 未連接
.withExternal()
.source(RegStatusEnum.REGISTERED)
.target(RegStatusEnum.UNCONNECTED)
.event(RegEventEnum.UN_REGISTER)
;
}這里,我以連接事件為案例,其中 source 指定原始狀態,target 指定目標狀態,event 指定觸發事件。
因此,下面的狀態就很好理解了,即當發生連接事件時,從未連接狀態變更為已連接狀態。
// 未連接 -> 已連接 .withExternal() .source(RegStatusEnum.UNCONNECTED) .target(RegStatusEnum.CONNECTED) .event(RegEventEnum.CONNECT)
狀態監聽器
Spring StateMachine 提供了注解配置實現方式,所有 StateMachineListener 接口中定義的事件都能通過注解的方式來進行配置實現。
@WithStateMachine
public class StateMachineEventConfig {
@OnTransition(source = "UNCONNECTED", target = "CONNECTED")
public void connect() {
System.out.println("///////////////////");
System.out.println("連接事件, 未連接 -> 已連接");
System.out.println("///////////////////");
}
@OnTransition(source = "CONNECTED", target = "REGISTERING")
public void register() {
System.out.println("///////////////////");
System.out.println("注冊事件, 已連接 -> 注冊中");
System.out.println("///////////////////");
}
@OnTransition(source = "REGISTERING", target = "REGISTERED")
public void registerSuccess() {
System.out.println("///////////////////");
System.out.println("注冊成功事件, 注冊中 -> 已注冊");
System.out.println("///////////////////");
}
@OnTransition(source = "REGISTERED", target = "UNCONNECTED")
public void unRegister() {
System.out.println("///////////////////");
System.out.println("注銷事件, 已注冊 -> 未連接");
System.out.println("///////////////////");
}
}這里,我仍然以連接事件為案例,@OnTransition 中 source 指定原始狀態,target 指定目標狀態,當事件觸發時將會被監聽到從而調用 connect() 方法。
總結
Spring StateMachine 讓狀態機結構更加層次化,可以幫助開發者簡化狀態機的開發過程。
我們來回顧下幾個核心步驟
定義狀態枚舉。
定義事件枚舉。
定義狀態機配置,設置初始狀態,以及狀態與事件之間的關系。
定義狀態監聽器,當狀態變更時,觸發方法。
到此,相信大家對“Spring中StateMachine狀態機的機制原理”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。