深入探讨StateMachine状态机机制的奥秘?

2026-06-10 15:261阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1243个文字,预计阅读时间需要5分钟。

深入探讨StateMachine状态机机制的奥秘?

前言:Spring StateMachine 让状态机结构更加强大,可以帮助开发者简化状态机的开发过程。

之前,我们使用二维数组实现状态机机制,现在,我们采用 Spring StateMachine 进行改造。

深入探讨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 让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。

我们来回顾下几个核心步骤

  • 定义状态枚举。
  • 定义事件枚举。
  • 定义状态机配置,设置初始状态,以及状态与事件之间的关系。
  • 定义状态监听器,当状态变更时,触发方法。

源代码

相关示例完整代码: springboot-action

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。

本文共计1243个文字,预计阅读时间需要5分钟。

深入探讨StateMachine状态机机制的奥秘?

前言:Spring StateMachine 让状态机结构更加强大,可以帮助开发者简化状态机的开发过程。

之前,我们使用二维数组实现状态机机制,现在,我们采用 Spring StateMachine 进行改造。

深入探讨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 让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。

我们来回顾下几个核心步骤

  • 定义状态枚举。
  • 定义事件枚举。
  • 定义状态机配置,设置初始状态,以及状态与事件之间的关系。
  • 定义状态监听器,当状态变更时,触发方法。

源代码

相关示例完整代码: springboot-action

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。