2025年通过实例学习SpringStateMachine之TURN STILE

通过实例学习SpringStateMachine之TURN STILE背景介绍 本系列通过学习 SpringStateM 中附带的 10 余个 Sample 来学习 SpringStateM 中的各个概念和用法 项目是使用的分支为 2 2 0 RELEASE 1 项目参考文档也是 2 2 0 RELEASE 1 TURN STILE 简介 turnstile 是对体育场入口或地铁入口的旋转栅门构建的状态机

大家好,我是讯享网,很高兴认识大家。

背景介绍

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

TURN STILE简介

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

状态机的两种状态:

  • LOCKED
  • UNLOCKED

状态机的两种事件

  • COIN
  • PUSH

触发相应事件后发生状态转换。
在这里插入图片描述
讯享网

TURN STILE 依赖

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

 <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 StateMachineConfig extends EnumStateMachineConfigurerAdapter<States, Events> { 
    @Override public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception { 
    states .withStates() .initial(States.LOCKED) .states(EnumSet.allOf(States.class)); } @Override public 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); } } 

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

  • @Configuration
  • @EnableStateMachine
  • EnumStateMachineConfigurerAdapter

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

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

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

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"; } } 

此外将官方AbstractStateMachineCommands[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>{ 
    @Autowired private 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 

总结

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

  • @Configuration,
  • @EnableStateMachine,
  • EnumStateMachineConfigurerAdapter

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

参考

[1]2.2.0.RELEASE source,https://github.com/spring-projects/spring-statemachine/blob/2.2.0.RELEASE/
[2]2.2.0.RELEASE/reference,https://docs.spring.io/spring-statemachine/docs/2.2.0.RELEASE/reference
[3]turnstile,https://docs.spring.io/spring-statemachine/docs/2.2.0.RELEASE/reference/#statemachine-examples-turnstile
[4]turnstile demo,https://github.com/spring-projects/spring-statemachine/tree/2.2.0.RELEASE/spring-statemachine-samples/turnstile/src/main/java/demo/turnstile
[5]StateMachineCommands,https://github.com/spring-projects/spring-statemachine/blob/2.2.0.RELEASE/spring-statemachine-samples/turnstile/src/main/java/demo/turnstile/StateMachineCommands.java
[6]AbstractStateMachineCommands,https://github.com/spring-projects/spring-statemachine/blob/2.2.0.RELEASE/spring-statemachine-samples/src/main/java/demo/AbstractStateMachineCommands.java

小讯
上一篇 2025-01-17 14:28
下一篇 2025-03-17 20:01

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/52147.html