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状态机的更多相关文章

  1. Spring Boot 揭秘与实战(七) 实用技术篇 - StateMachine 状态机机制

    文章目录 1. 环境依赖 2. 状态和事件 2.1. 状态枚举 2.2. 事件枚举 3. 状态机配置4. 状态监听器 3.1. 初始化状态机状态 3.2. 初始化状态迁移事件 5. 总结 6. 源代码 ...

  2. Spring Boot 2.x实战之StateMachine

    本文首发于个人网站:Spring Boot 2.x实战之StateMachine Spring StateMachine是一个状态机框架,在Spring框架项目中,开发者可以通过简单的配置就能获得一个 ...

  3. Spring Boot 1.5.x 基础学习示例

    一.为啥要学Spring Boot? 今年从原来.Net Team“被”转到了Java Team开始了微服务开发的工作,接触了Spring Boot这个新瓶装旧酒的技术,也初步了解了微服务架构.Spr ...

  4. Spring Boot 非常好的学习资料

    from@https://gitee.com/didispace/SpringBoot-Learning Spring Boot 2.0 新特性学习 简介与概览 Spring Boot 2.0 正式发 ...

  5. spring boot的日常配置

    配置篇 #数据库连接配置msql spring.datasource.url:jdbc:mysql://127.0.0.1:3306/test spring.datasource.username: ...

  6. spring boot 项目搭建时,各个依赖的作用

    项目搭建页面 https://start.spring.io/ 各个依赖的作用 List of dependencies for Spring Boot 2.1.5.RELEASE Core DevT ...

  7. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  8. 【微框架】之一:从零开始,轻松搞定SpringCloud微框架系列--开山篇(spring boot 小demo)

    Spring顶级框架有众多,那么接下的篇幅,我将重点讲解SpringCloud微框架的实现 Spring 顶级项目,包含众多,我们重点学习一下,SpringCloud项目以及SpringBoot项目 ...

  9. 玩转spring boot——开篇

    很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...

随机推荐

  1. ECMAScript5新特性之isSealed、seal

    封闭对象后: 1 不能增加属性. 2 不能删除属性. 3 可以修改属性.(赋值) 4 不能修改属性描述符.(抛异常) var fruit = { name : '苹果', desc : '红富士' } ...

  2. 【原创】Junit4详解二:Junit4 Runner以及test case执行顺序和源代码理解

    概要: 前一篇文章我们总体介绍了Junit4的用法以及一些简单的测试.之前我有个疑惑,Junit4怎么把一个test case跑起来的,在test case之前和之后我们能做些什么? Junit4执行 ...

  3. macos修改vmware Fusion的NAT网络

    https://blog.csdn.net/zhishengqianjun/article/details/77046796 http://pubs.vmware.com/fusion-5/index ...

  4. svn回退版本/取消修改

    取消对代码的修改分为两种情况:   第一种情况:改动没有被提交(commit). 这种情况下,使用svn revert就能取消之前的修改. svn revert用法如下: # svn revert [ ...

  5. python如何查看有哪些模块

    Question: 如何查看正则表达式模块re及其相关函数的意义 1.终端命令行下 python >> import sys >> sys.modules ########## ...

  6. 关于UI设计的一些工作了解

    关于UI设计相信大家在刚接触UI的时候都不太了解,我来说说我在一段学习时间后的了解. UI从工作内容上来说分为3大类,即研究工具,研究人与界面的关系,研究人与之相应. ​ UI设计师的职能一个是图形设 ...

  7. laravel增删改查(查询构建器)

    1.增 $data = [ 'username' => 'xiaohong', 'nickname' => '小红红', 'email' => '12356788@qq.com', ...

  8. UI设计:掌握这6点,轻松0到1

    非科班出身能成为UI设计师吗? 答案是肯定的.世上无难事,只怕有心人.只要找对方法.坚持不懈,即便是零基础也能学好UI设计. 那么零基础学习UI设计,需要学习哪些知识?我们要从哪些地方学起?怎么系统学 ...

  9. java网络爬虫实现信息的抓取

    转载请注明出处:http://blog.csdn.NET/lmj623565791/article/details/23272657 今天公司有个需求,需要做一些指定网站查询后的数据的抓取,于是花了点 ...

  10. 2018.09.16 bzoj3757: 苹果树(树上莫队)

    传送门 一道树上莫队. 先用跟bzoj1086一样的方法给树分块. 分完之后就可以莫队了. 但是两个询问之间如何转移呢? 感觉很难受啊. 我们定义S(u,v)" role="pre ...