本篇内容主要讲解“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状态机的机制原理”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。