博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring系列学习之Spring Statemachine状态机
阅读量:148 次
发布时间:2019-02-28

本文共 8233 字,大约阅读时间需要 27 分钟。

英文原文:

目录


Spring Statemachine是应用程序开发人员在Spring应用程序中使用状态机概念的框架。

Spring Statemachine旨在提供以下功能:

  •     易于使用的扁平单级状态机,用于简单的使用案例。
  •     分层状态机结构,以简化复杂的状态配置。
  •     状态机区域提供更复杂的状态配置。
  •     使用触发器,转换,警卫和操作。
  •     键入安全配置适配器。
  •     生成器模式,用于在Spring Application上下文之外使用的简单实例化
  •     通常用例的食谱
  •     基于Zookeeper的分布式状态机
  •     状态机事件监听器。
  •     UML Eclipse Papyrus建模。
  •     将计算机配置存储在永久存储中。
  •     Spring IOC集成将bean与状态机关联起来。

状态机功能强大,因为行为始终保证一致,使调试相对容易。这是因为操作规则是在机器启动时写成的。这个想法是你的应用程序可能存在于有限数量的状态中,某些预定义的触发器可以将你的应用程序从一个状态转移到另一个状态。此类触发器可以基于事件或计时器。
在应用程序之外定义高级逻辑然后依靠状态机来管理状态要容易得多。您可以通过发送事件,侦听更改或仅请求当前状态来与状态机进行交互。
你想问一个问题吗?转到并使用标签或。

快速开始

在项目中使用spring-statemachine的推荐方法是使用依赖关系管理系统 - 下面的代码片段可以复制并粘贴到您的构建中。 需要帮忙? 请参阅我们的Maven和Gradle构建入门指南。(导航到英文页面可以选择版本和依赖方式)

Maven

org.springframework.statemachine
spring-statemachine-core
2.0.3.RELEASE

Gradle

dependencies {    compile 'org.springframework.statemachine:spring-statemachine-core:2.0.3.RELEASE'}

以下示例应该了解如何配置和使用状态机。 假设我们有状态STATE1,STATE2和事件EVENT1,EVENT2。

static enum States {    STATE1, STATE2}static enum Events {    EVENT1, EVENT2}

 

Builder

public StateMachine
buildMachine() throws Exception { Builder
builder = StateMachineBuilder.builder(); builder.configureStates() .withStates() .initial(States.STATE1) .states(EnumSet.allOf(States.class)); builder.configureTransitions() .withExternal() .source(States.STATE1).target(States.STATE2) .event(Events.EVENT1) .and() .withExternal() .source(States.STATE2).target(States.STATE1) .event(Events.EVENT2); return builder.build();}
StateMachine
stateMachine = buildMachine();stateMachine.start();stateMachine.sendEvent(Events.EVENT1);stateMachine.sendEvent(Events.EVENT2);

JavaConfig

@Configuration@EnableStateMachinestatic class Config1 extends EnumStateMachineConfigurerAdapter
{ @Override public void configure(StateMachineStateConfigurer
states) throws Exception { states .withStates() .initial(States.STATE1) .states(EnumSet.allOf(States.class)); } @Override public void configure(StateMachineTransitionConfigurer
transitions) throws Exception { transitions .withExternal() .source(States.STATE1).target(States.STATE2) .event(Events.EVENT1) .and() .withExternal() .source(States.STATE2).target(States.STATE1) .event(Events.EVENT2); }}
@WithStateMachinestatic class MyBean {    @OnTransition(target = "STATE1")    void toState1() {    }    @OnTransition(target = "STATE2")    void toState2() {    }}
static class MyApp {    @Autowired    StateMachine
stateMachine; void doSignals() { stateMachine.start(); stateMachine.sendEvent(Events.EVENT1); stateMachine.sendEvent(Events.EVENT2); }}

 

版本

Spring Statemachine

Release

Documentation

2.1.0 M1

2.1.0

2.0.4

2.0.3

1.2.13

1.2.12

1.1.1

资源

实战

封装消息数据:

package com.patrol.position;import com.patrol.beans.user.UserPosition;import com.patrol.position.stateMachine.Events;import com.patrol.position.stateMachine.States;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;import org.springframework.messaging.Message;import org.springframework.messaging.support.MessageBuilder;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.statemachine.StateMachine;import springfox.documentation.swagger2.annotations.EnableSwagger2;/** * 开启异步请求 */@EnableAsync/** * 开启接口缓存 */@EnableCaching/** * 开启定时任务调度 */@EnableScheduling/** * 开启接口文档描述 */@EnableSwagger2/** * @SpringBootApplication * 

相当于@Configuration,@EnableAutoConfiguration和 @ComponentScan

*/@SpringBootApplicationpublic class PatrolPositionServiceApplication implements CommandLineRunner { @Autowired StateMachine
stateMachine; @Override public void run(String... args) throws Exception { stateMachine.start(); // 发送上线位置数据 UserPosition userPosition = new UserPosition(); userPosition.setUserId("123434"); userPosition.setLive(true); userPosition.setPosition(new Double[]{103.2342343,31.23894343}); Message userPositionMessage = MessageBuilder.withPayload(Events.ONLINE).setHeader("position",userPosition).build(); stateMachine.sendEvent(userPositionMessage); // 发送离线位置数据 userPosition = new UserPosition(); userPositionMessage = MessageBuilder.withPayload(Events.OFFLINE).setHeader("position",userPosition).build(); stateMachine.sendEvent(userPositionMessage); } public static void main(String[] args) { SpringApplication.run(PatrolPositionServiceApplication.class, args); }}

消息监听处理:

package com.patrol.position.stateMachine;import com.alibaba.fastjson.JSON;import com.patrol.beans.user.UserPosition;import lombok.extern.slf4j.Slf4j;import org.springframework.messaging.Message;import org.springframework.statemachine.StateMachine;import org.springframework.statemachine.annotation.OnTransition;import org.springframework.statemachine.annotation.WithStateMachine;/** * @Copyright: 2019-2021 * @FileName: UserStateMachineService.java * @Author: PJL * @Date: 2021/1/25 17:40 * @Description: 用户状态机监听 */@Slf4j@WithStateMachinepublic class StateMachineListener {    /**     * 获取业务数据     * @param message     * @return     */    private UserPosition getUserPosition( Message message){        if(null == message|| null == message.getHeaders()){            return null;        }        return (UserPosition)message.getHeaders().get("position");    }    /**     * 用户在线     * @param stateMachine     * @param message     */    @OnTransition(target = "ONLINE")    public void userOnline(StateMachine
stateMachine, Message message) { log.info("用户状态机:======用户上线!======{}",stateMachine); UserPosition userPosition = this.getUserPosition(message); log.info("上线传入位置:" + JSON.toJSONString(userPosition)); } /** * 用户离线 * @param stateMachine * @param message */ @OnTransition(target = "OFFLINE") public void userOffline(StateMachine
stateMachine, Message message) { log.info("用户状态机:======用户下线!======{}",stateMachine); UserPosition userPosition = this.getUserPosition(message); log.info("下线传入位置:" + JSON.toJSONString(userPosition)); }}

效果输出:

2021-01-26 10:56:46.731 [restartedMain] INFO  c.p.p.PatrolPositionServiceApplication | Started PatrolPositionServiceApplication in 32.654 seconds (JVM running for 37.851)2021-01-26 10:56:46.841 [restartedMain] INFO  c.p.p.s.StateMachineListener | 用户状态机:======用户下线!======OFFLINE ONLINE  /  / uuid=c32e1ba9-7fa4-49a4-8fed-74cd40f0ac46 / id=null2021-01-26 10:56:46.842 [restartedMain] INFO  c.p.p.s.StateMachineListener | 下线传入位置:null2021-01-26 10:56:46.854 [restartedMain] INFO  o.s.s.s.LifecycleObjectSupport | started org.springframework.statemachine.support.DefaultStateMachineExecutor@7ad0542f2021-01-26 10:56:46.855 [restartedMain] INFO  o.s.s.s.LifecycleObjectSupport | started OFFLINE ONLINE  / OFFLINE / uuid=c32e1ba9-7fa4-49a4-8fed-74cd40f0ac46 / id=null2021-01-26 10:56:46.869 [restartedMain] INFO  c.p.p.s.StateMachineListener | 用户状态机:======用户上线!======OFFLINE ONLINE  / OFFLINE / uuid=c32e1ba9-7fa4-49a4-8fed-74cd40f0ac46 / id=null2021-01-26 10:56:46.930 [restartedMain] INFO  c.p.p.s.StateMachineListener | 上线传入位置:{"distance":0.0,"live":true,"position":[103.2342343,31.23894343],"status":0,"time":0,"timestamp":0,"userId":"123434"}2021-01-26 10:56:46.933 [restartedMain] INFO  c.p.p.s.StateMachineListener | 用户状态机:======用户下线!======OFFLINE ONLINE  / ONLINE / uuid=c32e1ba9-7fa4-49a4-8fed-74cd40f0ac46 / id=null2021-01-26 10:56:46.933 [restartedMain] INFO  c.p.p.s.StateMachineListener | 下线传入位置:{"distance":0.0,"live":false,"status":0,"time":0,"timestamp":0}

参考文章:

转载地址:http://gmxj.baihongyu.com/

你可能感兴趣的文章