Spring Boot - StateMachine状态机
- 是Spring Boot提供的状态机的现成实现。
- 理论(有点像工作流)
- 需要定义一些状态的枚举,以及一些引起状态变化的事件的枚举。
- 每个状态可以对应的创建一个继承自org.springframework.statemachine.action.Action的类,用来在重写的execute方法中做动作并且通过sendEvent触发状态改变到下一状态。
- 那么在切换到下一状态时,就会自动触发相应的Action
- 参考
- 使用
- 定义状态、事件的枚举
public enum SimulatorStates
{
IDLE,
ASSET_CREATION,
ONBOARDING,
ASSET_CONFIGURATION,
TEMPLATE_ASSIGNMENT,
STOP,
ERROR
}
public enum SimulatorStateMachineEvent
{
IDLE,
CREATE_ASSET,
ONBOARD,
CONFIGURE_ASSET,
ASSIGN_TEMPLATE,
STOP,
RE_IDLE,
ERROR
}
* 配置/构建状态机
* 方式一
* 使用StateMachineFactory
ObjectStateMachineFactory<String, String> machineFactory = new ObjectStateMachineFactory<String, String>(machineModel);
StateMachine<String, String> stateMachine = machineFactory.getStateMachine();
* 方式二
* 使用StateMachineBuilder
* 方式三
* **使用配置类配置状态机,如每个状态State对应的处理逻辑Action,什么事件Event会导致哪些状态State间切换,)**
@Configuration
@EnableStateMachineFactory
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<SimulatorStates, SimulatorStateMachineEvent>
{
@Override
public void configure(StateMachineStateConfigurer<SimulatorStates, SimulatorStateMachineEvent> states) throws Exception {
states.withStates().initial(SimulatorStates.IDLE)
.state(SimulatorStates.IDLE, getIdleAction())
.state(SimulatorStates.ASSET_CREATION, getAssetCreationAction())
.state(SimulatorStates.ONBOARDING, getOnboardingAction())
.state(SimulatorStates.ASSET_CONFIGURATION, getAssetConfigurationAction())
.state(SimulatorStates.TEMPLATE_ASSIGNMENT, getTemplateAssignmentAction())
.state(SimulatorStates.STOP, getStopAction())
.state(SimulatorStates.ERROR, getErrorAction());
}
@Override
public void configure(StateMachineTransitionConfigurer<SimulatorStates, SimulatorStateMachineEvent> transitions) throws Exception {
transitions.
withExternal().source(SimulatorStates.IDLE).target(SimulatorStates.ASSET_CREATION).event(SimulatorStateMachineEvent.CREATE_ASSET).and().
withExternal().source(SimulatorStates.ASSET_CREATION).target(SimulatorStates.ONBOARDING).event(SimulatorStateMachineEvent.ONBOARD).and().
withExternal().source(SimulatorStates.ONBOARDING).target(SimulatorStates.ASSET_CONFIGURATION).event(SimulatorStateMachineEvent.CONFIGURE_ASSET).and().
withExternal().source(SimulatorStates.ASSET_CONFIGURATION).target(SimulatorStates.TEMPLATE_ASSIGNMENT).event(SimulatorStateMachineEvent.ASSIGN_TEMPLATE).and().
withExternal().source(SimulatorStates.TEMPLATE_ASSIGNMENT).target(SimulatorStates.STOP).event(SimulatorStateMachineEvent.STOP).and().
withExternal().source(SimulatorStates.STOP).target(SimulatorStates.IDLE).event(SimulatorStateMachineEvent.RE_IDLE).and().
withExternal().source(SimulatorStates.ASSET_CREATION).target(SimulatorStates.ERROR).event(SimulatorStateMachineEvent.ERROR).and().
withExternal().source(SimulatorStates.ONBOARDING).target(SimulatorStates.ERROR).event(SimulatorStateMachineEvent.ERROR).and().
withExternal().source(SimulatorStates.ASSET_CONFIGURATION).target(SimulatorStates.ERROR).event(SimulatorStateMachineEvent.ERROR).and().
withExternal().source(SimulatorStates.TEMPLATE_ASSIGNMENT).target(SimulatorStates.ERROR).event(SimulatorStateMachineEvent.ERROR).and().
withExternal().source(SimulatorStates.STOP).target(SimulatorStates.ERROR).event(SimulatorStateMachineEvent.ERROR).and().
withExternal().source(SimulatorStates.ERROR).target(SimulatorStates.IDLE).event(SimulatorStateMachineEvent.RE_IDLE);
}
@Bean(name = "stateMachineTaskScheduler")
public ConcurrentTaskScheduler myStateMachineTaskScheduler() {
ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(4);
return new ConcurrentTaskScheduler(threadPool);
}
@Override
public void configure(StateMachineConfigurationConfigurer<SimulatorStates, SimulatorStateMachineEvent> config) throws Exception {
config.withConfiguration().taskScheduler(myStateMachineTaskScheduler());
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getIdleAction() {
return new Idle();
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getAssetCreationAction() {
return new AssetCreation();
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getOnboardingAction() {
return new Onboarding();
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getAssetConfigurationAction() {
return new AssetConfiguration();
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getTemplateAssignmentAction() {
return new TemplateAssignment();
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getStopAction() {
return new StopAction();
}
@Bean
Action<SimulatorStates, SimulatorStateMachineEvent> getErrorAction() {
return new ErrorAction();
}
}
* 启动状态机
* stateMachine.start();
@Component
public class StateExecutor
{
@Autowired
private StateMachineFactory<SimulatorStates, SimulatorStateMachineEvent> stateMachineFactory;
public void runStates(AssetTestInfo assetTestInfo) {
StateMachine<SimulatorStates,SimulatorStateMachineEvent> stateMachine = stateMachineFactory.getStateMachine();
stateMachine.getExtendedState().getVariables().put(SimulatorConstants.ASSET_TEST_INFO, assetTestInfo);
stateMachine.start();
}
}
* 定义Action处理逻辑
* 设置变量?
* stateMachine.getExtendedState().getVariables().put(SimulatorConstants.ASSET_TEST_INFO, assetTestInfo);
* 发送/触发事件
* stateMachine.sendEvent(Events.PAY);
* context.getStateMachine().sendEvent(SimulatorStateMachineEvent.CONFIGURE_ASSET);
public class AssetConfiguration implements Action<SimulatorStates, SimulatorStateMachineEvent>
{
private static final Logger logger = LoggerFactory.getLogger(AssetConfiguration.class);
@Autowired
private AssetConfigurationService assetConfigurator;
@Override
public void execute(StateContext<SimulatorStates, SimulatorStateMachineEvent> context)
{
AssetTestInfo assetTestInfo = AssetTestInfo.class.cast(context.getExtendedState().getVariables().get(SimulatorConstants.ASSET_TEST_INFO));
logger.debug("Asset Configuration State Start for asset: {}", assetTestInfo.getAssetId());
try {
assetConfigurator.execute(assetTestInfo);
context.getStateMachine().sendEvent(SimulatorStateMachineEvent.ASSIGN_TEMPLATE);
} catch (Exception e) {
logger.error("Cannot complete asset configuration", e);
context.getStateMachine().sendEvent(SimulatorStateMachineEvent.ERROR);
}
logger.debug("Asset Configuration State End for asset: {}", assetTestInfo.getAssetId());
}
}
Spring Boot - StateMachine状态机的更多相关文章
- Spring Boot 揭秘与实战(七) 实用技术篇 - StateMachine 状态机机制
文章目录 1. 环境依赖 2. 状态和事件 2.1. 状态枚举 2.2. 事件枚举 3. 状态机配置4. 状态监听器 3.1. 初始化状态机状态 3.2. 初始化状态迁移事件 5. 总结 6. 源代码 ...
- Spring Boot 2.x实战之StateMachine
本文首发于个人网站:Spring Boot 2.x实战之StateMachine Spring StateMachine是一个状态机框架,在Spring框架项目中,开发者可以通过简单的配置就能获得一个 ...
- Spring Boot 1.5.x 基础学习示例
一.为啥要学Spring Boot? 今年从原来.Net Team“被”转到了Java Team开始了微服务开发的工作,接触了Spring Boot这个新瓶装旧酒的技术,也初步了解了微服务架构.Spr ...
- Spring Boot 非常好的学习资料
from@https://gitee.com/didispace/SpringBoot-Learning Spring Boot 2.0 新特性学习 简介与概览 Spring Boot 2.0 正式发 ...
- spring boot的日常配置
配置篇 #数据库连接配置msql spring.datasource.url:jdbc:mysql://127.0.0.1:3306/test spring.datasource.username: ...
- spring boot 项目搭建时,各个依赖的作用
项目搭建页面 https://start.spring.io/ 各个依赖的作用 List of dependencies for Spring Boot 2.1.5.RELEASE Core DevT ...
- 玩转spring boot——快速开始
开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...
- 【微框架】之一:从零开始,轻松搞定SpringCloud微框架系列--开山篇(spring boot 小demo)
Spring顶级框架有众多,那么接下的篇幅,我将重点讲解SpringCloud微框架的实现 Spring 顶级项目,包含众多,我们重点学习一下,SpringCloud项目以及SpringBoot项目 ...
- 玩转spring boot——开篇
很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...
随机推荐
- 在c#中设置Excel格式
生成excel的时候有时候需要设置单元格的一些属性,可以参考一下: range.NumberFormatLocal = "@"; //设置单元格格式为文本 ange.get_Ran ...
- 【转】Hadoop HDFS分布式环境搭建
原文地址 http://blog.sina.com.cn/s/blog_7060fb5a0101cson.html Hadoop HDFS分布式环境搭建 最近选择给大家介绍Hadoop HDFS系统 ...
- MVC加载部分视图Partial
加载部分视图的方法:Partial() .RenderPartial() . Action() .RenderAction() . RenderPage() partial 与 RenderParti ...
- jetty 8.0 add filter example
http://zyn010101.iteye.com/blog/1679798 package com.cicc.gaf.sso.server;import java.io.IOException;i ...
- Golang之Mysql操作
话说当年武大郎对着电脑一顿噼里啪啦,,,对mysql增删改查 增加insert package main import ( "fmt" "github.com/jmoir ...
- 【Linux】SVN的安装和配置
SVN SVN:SVN是Subversion的简称,是一种开放代码的版本控制系统,相比较RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制器服务已从CVS迁移到Su ...
- [转载红鱼儿]Delphi XE7 update1进步太大了
写以下的文字是怀着无比兴奋的心情写的,急于同朋友们分享XE7的进步! 1.更新的bug列表并不全 通过bug修正列表及发布的消息,可以看到up1修正了很多bug,正如我所说,有些bug并没有写到发布的 ...
- js中为什么非要alert一下下一步才会执行
多数原因为界面ajax中动态添加的元素还没被添加上,就执行了js函数(js函数要调用动态元素),解决办法:ajax方法中添加 async:false,同步,作用为,在ajax执行完毕后才执行之后的js ...
- 2018.07.17 洛谷P1368 工艺(最小表示法)
传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头 ...
- angularjs写公共方法
'use strict'; angular.module('fast-westone') .factory('commonUtilService', function () { return { /* ...