StateMachine 状态机机制深入解析
前言
SpringStateMachine让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。
之前,我们使用二维数组实现状态机机制,现在,我们来用SpringStateMachine进行改造。
环境依赖
修改POM文件,添加spring-statemachine-core依赖。
org.springframework.statemachine spring-statemachine-core 1.2.0.RELEASE
状态和事件
现在,我以用户注册为案例,来讲解状态和事件之间的状态机机制。
状态枚举
注册有哪些状态呢,我们来想想,应该有4个状态:未连接、已连接、注册中、已注册。
publicenumRegStatusEnum{ //未连接 UNCONNECTED, //已连接 CONNECTED, //注册中 REGISTERING, //已注册 REGISTERED; }
事件枚举
相对应的,存在几个核心事件:连接、注册、注册成功、注册失败、注销。
publicenumRegEventEnum{ //连接 CONNECT, //注册 REGISTER, //注册成功 REGISTER_SUCCESS, //注册失败 REGISTER_FAILED, //注销 UN_REGISTER; }
状态机配置
@Configuration @EnableStateMachine publicclassStateMachineConfigextendsEnumStateMachineConfigurerAdapter{ }
@EnableStateMachine注解,标识启用SpringStateMachine状态机功能。
初始化状态机状态
我们需要初始化状态机的状态。
@Override publicvoidconfigure(StateMachineStateConfigurerstates)throwsException{ states.withStates() //定义初始状态 .initial(RegStatusEnum.UNCONNECTED) //定义状态机状态 .states(EnumSet.allOf(RegStatusEnum.class)); }
其中,initial(RegStatusEnum.UNCONNECTED)定义了初始状态是未连接状态。states(EnumSet.allOf(RegStatusEnum.class))定义了定义状态机中存在的所有状态。
初始化状态迁移事件
我们需要初始化当前状态机有哪些状态事件。
@Override publicvoidconfigure(StateMachineTransitionConfigurertransitions) throwsException{ 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)
状态监听器
SpringStateMachine提供了注解配置实现方式,所有StateMachineListener接口中定义的事件都能通过注解的方式来进行配置实现。
@WithStateMachine publicclassStateMachineEventConfig{ @OnTransition(source="UNCONNECTED",target="CONNECTED") publicvoidconnect(){ System.out.println("///////////////////"); System.out.println("连接事件,未连接->已连接"); System.out.println("///////////////////"); } @OnTransition(source="CONNECTED",target="REGISTERING") publicvoidregister(){ System.out.println("///////////////////"); System.out.println("注册事件,已连接->注册中"); System.out.println("///////////////////"); } @OnTransition(source="REGISTERING",target="REGISTERED") publicvoidregisterSuccess(){ System.out.println("///////////////////"); System.out.println("注册成功事件,注册中->已注册"); System.out.println("///////////////////"); } @OnTransition(source="REGISTERED",target="UNCONNECTED") publicvoidunRegister(){ System.out.println("///////////////////"); System.out.println("注销事件,已注册->未连接"); System.out.println("///////////////////"); } }
这里,我仍然以连接事件为案例,@OnTransition中source指定原始状态,target指定目标状态,当事件触发时将会被监听到从而调用connect()方法。
总结
SpringStateMachine让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。
我们来回顾下几个核心步骤
- 定义状态枚举。
- 定义事件枚举。
- 定义状态机配置,设置初始状态,以及状态与事件之间的关系。
- 定义状态监听器,当状态变更时,触发方法。
源代码
相关示例完整代码:springboot-action
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。