首页 >> 大全

通过实例学习SpringStateMachine之TURN STILE

2024-01-03 大全 30 作者:考证青年

背景介绍

本系列通过学习中附带的10余个来学习中的各个概念和用法。项目是使用的分支为2.2.0.[1]。项目参考文档也是2.2.0.[1]。

TURN STILE简介

是对体育场入口或地铁入口的旋转栅门构建的状态机。

状态机的两种状态:

状态机的两种事件

触发相应事件后发生状态转换

TURN STILE 依赖

项目在实现上述功能时,需要依赖,官方给出的demo[4]使用了-.2,本文将其改为-shell 2.0.0.。

        <dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-core</artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework.shell</groupId><artifactId>spring-shell-starter</artifactId><version>2.0.0.RELEASE</version></dependency>

TURN STILE 实现

为了实现本例,我们需要描述状态及其转换。首先定义状态与事件枚举类型。

状态枚举类型:

public enum States {LOCKED, UNLOCKED
}

使状态发生变化的事件枚举类型:

public enum Events {COIN, PUSH
}

接着我们配置状态与转换。

package springboot.statemachine.example.turnstile.demo;import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;import java.util.EnumSet;@Configuration
@EnableStateMachine
public class StateMachineConfigextends EnumStateMachineConfigurerAdapter<States, Events> {@Overridepublic void configure(StateMachineStateConfigurer<States, Events> states)throws Exception {states.withStates().initial(States.LOCKED).states(EnumSet.allOf(States.class));}@Overridepublic void configure(StateMachineTransitionConfigurer<States, Events> transitions)throws Exception {transitions.withExternal().source(States.LOCKED).target(States.UNLOCKED).event(Events.COIN).and().withExternal().source(States.UNLOCKED).target(States.LOCKED).event(Events.PUSH);}}

在配置状态与转换时用到如下的注解与类:

代码继承类,并覆盖两个方法,在这两个方法中分别来配置转换与状态列表同时指定好初始状态。

随后在创建的类上增加@与@注解,通过这些创建状态机实例,系统随后会检测是否使用了类,并在运行时根据这些配置修改状态机。

中有三种形式的转换(), , local。

这里我们使用了,返回一个来完成转换的配置。方法指定了目标状态,指定了源状态,event指定了使状态发生变更的事件。

最后是命令实现。这里对官方demo[5]进行了小修改。最后通过的方法发送事件,使状态机状态发生变化。

import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import springboot.statemachine.example.AbstractStateMachineCommands;@ShellComponent
public class StateMachineCommands extends AbstractStateMachineCommands<States, Events> {@ShellMethod(key = "sm event", value = "Sends an event to a state machine")public String event(Events event) {getStateMachine().sendEvent(event);return "Event " + event + " send";}
}

此外将官方[6]中打印turn stile字符图形的部分去掉了。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.state.State;
import org.springframework.util.StringUtils;import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;public class AbstractStateMachineCommands<S, E>{@Autowiredprivate StateMachine<S, E> stateMachine;protected StateMachine<S, E> getStateMachine() {return stateMachine;}@ShellMethod(key = "sm state", value = "Prints current state")public String state() {State<S, E> state = stateMachine.getState();if (state != null) {return StringUtils.collectionToCommaDelimitedString(state.getIds());} else {return "No state";}}@ShellMethod(key = "sm start", value = "Start a state machine")public String start() {stateMachine.start();return "State machine started";}@ShellMethod(key = "sm stop", value = "Stop a state machine")public String stop() {stateMachine.stop();return "State machine stopped";}@ShellMethod(key = "sm variables", value = "Prints extended state variables")public String variables() {StringBuilder buf = new StringBuilder();Set<Entry<Object, Object>> entrySet = stateMachine.getExtendedState().getVariables().entrySet();Iterator<Entry<Object, Object>> iterator = entrySet.iterator();if (entrySet.size() > 0) {while (iterator.hasNext()) {Entry<Object, Object> e = iterator.next();buf.append(e.getKey() + "=" + e.getValue());if (iterator.hasNext()) {buf.append("\n");}}} else {buf.append("No variables");}return buf.toString();}}

验证

发送不同的命令触发事件,并查看状态机当前状态,发现状态正确发生变化。

State machine started
shell:>sm event COIN
Event COIN send
shell:>sm event PUSH
Event PUSH send
shell:>sm start
State machine started
shell:>sm state
LOCKED
shell:>sm event COIN
Event COIN send
shell:>sm state
UNLOCKED
shell:>sm event PUSH
Event PUSH send
shell:>sm state
LOCKED
shell:>sm event PUSH
Event PUSH send
shell:>sm state
LOCKED
shell:>sm state COIN
LOCKED
shell:>sm state
LOCKED
shell:>sm start
State machine started
shell:>sm state
LOCKED
shell:>sm stop

总结

通过这个例子学习了基础的概念及相关配置。通过

完成配置及创建单实例。实现触发事件使状态机当前状态发生变化,从源状态到目标状态变化。

参考

[1]2.2.0. ,

[2]2.2.0./,

[3],#--

[4] demo,

[5],

[6],

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了