前言

Spring StateMachine 让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。

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

环境依赖

修改 POM 文件,添加 spring-statemachine-core 依赖。

org.springframework.statemachine

spring-statemachine-core

1.2.0.RELEASE

状态和事件

现在,我以用户注册为案例,来讲解状态和事件之间的状态机机制。

状态枚举

注册有哪些状态呢,我们来想想,应该有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 {

}

@EnableStateMachine注解,标识启用 Spring StateMachine 状态机功能。

初始化状态机状态

我们需要初始化状态机的状态。

@Override

public void configure(StateMachineStateConfigurer 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 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 让状态机结构更加层次化,可以帮助开发者简化状态机的开发过程。

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

定义状态枚举。

定义事件枚举。

定义状态机配置,设置初始状态,以及状态与事件之间的关系。

定义状态监听器,当状态变更时,触发方法。

源代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持谷谷点程序。

java statemachine_StateMachine 状态机机制深入解析相关推荐

  1. Java 异步回调机制实例解析

    2019独角兽企业重金招聘Python工程师标准>>> 一.什么是回调 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用. 回调是一种特殊 ...

  2. 深入探索Java反射机制:解析原理与应用

    深入探索Java反射机制:解析原理与应用

  3. java 异步通知_Java 异步回调机制实例解析

    什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道"就一个回调-".此时千万个草泥马飞奔而过 哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉.不妨总结总结. 一.什么 ...

  4. Java的类加载机制

    jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card table数据结构 Java类初始化顺序 J ...

  5. 深入理解Java Class反射机制

    本篇主要是深入对Java中的Class对象进行分析,这对后续深入理解反射技术非常重要,这篇有点偏向内功类文章. 深入理解Class对象 RRTI的概念以及Class对象作用 认识Class对象之前,先 ...

  6. 【转】Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9153761 记得在前面的文章中,我带大家一起从源码的角度分析了Android中Vi ...

  7. 高级开发必须理解的Java中SPI机制

    本文通过探析JDK提供的,在开源项目中比较常用的Java SPI机制,希望给大家在实际开发实践.学习开源项目提供参考. 1 SPI是什么 SPI全称Service Provider Interface ...

  8. 浅析java内存管理机制

    内存管理是计算机编程中的一个重要问题,一般来说,内存管理主要包括内存分配和内存回收两个部分.不同的编程语言有不同的内存管理机制,本文在对比C++和java语言内存管理机制的不同的基础上,浅析java中 ...

  9. 36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC

    36.JVM内存分哪几个区,每个区的作用是什么? 37.如和判断一个对象是否存活?(或者GC对象的判定方法) 38.简述java垃圾回收机制? 39.java中垃圾收集的方法有哪些? 40.java类 ...

最新文章

  1. 绘制测试集、训练集的每一个病人或者样本的raidomics signiture图(绘制raidomics signature图),以及ROC曲线图
  2. arcgis api for flex 开发入门(九)webservices 的使用
  3. Java学习之键盘输入输出小程序
  4. c语言getchar用法_C语言 — 关键字
  5. Nginx 源码分析:ngx_hash_t(上)
  6. python2.7与python3的区别_Python 2.7 与Python3的区别
  7. python写TCP协议
  8. HFS远程命令执行漏洞入侵抓鸡黑阔服务器
  9. 全志V3S学习笔记(二)PCF8563
  10. 如何才能高效学习,99%的人不知道的高效学习法
  11. Ubuntu cd 命令
  12. oracle查询本周本月本季本年时间
  13. 恭喜马斯克、纳德拉当选美国工程院院士,张宏江、方岱宁入选外籍院士
  14. #优质代码# Map按Value降序排序,Value相同时按Key排序
  15. 信源剩余度的计算java_冗余度计算公式
  16. 解密微信小程序用户敏感数据获取用户信息
  17. 一年月份大小月口诀_大月小月口诀 什么意思 有多少天
  18. windows下golang监控鼠标和键盘事件
  19. CSP-J 2021-网络连接
  20. 采样定理 ADC采样

热门文章

  1. 开发人员生产力指南,细节决定成败!
  2. GitHub 超 20000 Star,最火开源视频库 FFmpeg 这 20 年!
  3. 无代码时代下,程序员不够用了!
  4. 从开源开发者身上学到的 5 种品质
  5. 如何从零开始制作智能桌宠?
  6. 一个数据的乔迁奇遇记
  7. 程序员如何更好地获取用户信息?
  8. 5G 兴起,物联网安全危机四伏
  9. 5G 基站为何建得比 4G 多?
  10. 果断 Mark!27 个免费、低成本 Python 学习资源入手!