Spring 状态机(二)
前言
状态机能够实现状态的跳转,这种运用场景在实际中十分频繁地出现,在我们的经常使用的app中,几乎都有注册,注销功能,如果利用平时的转换逻辑其实也能够实现目标,但是作为新时代程序员必须尝试一下状态机。
实现总结
1.状态:首先注册模块我们已经相当熟悉,应该有4个状态:未连接、已连接、注册中、已注册。我们的目的就是实现这些逻辑合乎逻辑的流转。
public enum RegStatusEnum {
// 未连接
UNCONNECTED,
// 已连接
CONNECTED,
// 注册中
REGISTERING,
// 已注册
REGISTERED;
}
2.确定事件
//事件:连接、注册、注册成功、注册失败、注销。
public enum RegEventEnum {
// 连接
CONNECT,
// 注册
REGISTER,
// 注册成功
REGISTER_SUCCESS,
// 注册失败
REGISTER_FAILED,
// 注销
UN_REGISTER;
}
3.配置状态机,我们要做的其实是两块工作:初始化状态机状态和初始化状态迁移事件。
@Configuration
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<RegStatusEnum, RegEventEnum> {
@Override
public void configure(StateMachineStateConfigurer<RegStatusEnum, RegEventEnum> states) throws Exception {
states.withStates()// 定义初始状态
.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);
}
}
4.状态监听器
@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("///");
}
}
Spring StateMachine 让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。我们来回顾下几个核心步骤:
定义状态枚举。
定义事件枚举。
定义状态机配置,设置初始状态,以及状态与事件之间的关系。
定义状态监听器,当状态变更时,触发方法。