java - 如何处理spring状态机未处理的事件

标签 java spring spring-statemachine

假设我们有以下状态机配置:

transitions.withExternal()
    .source(FIRST)
    .target(SECOND)
    .event(STEP_EVENT)

    .and()

    .source(SECOND)
    .target(EXIT)
    .event(EXIT_EVENT)

事件列表:STEP_EVENT、EXIT_EVENT、UNUSED_EVENT

stateMachine.init(); 
// FIRST state

stateMachine.sendEvent(STEP_EVENT); 
/* state moves to SECOND 
because there is a transition with current state as a source 
and STEP_EVENT as transition event */

stateMachine.sendEvent(UNUSED_EVENT); 
/* no state change. 
This will trigger "eventNotAccepted(Message<Events> event)" 
in state machine listener, 
because UNUSED_EVENT is never mentioned in SM config */

stateMachine.sendEvent(STEP_EVENT); 
/* nothing will happen!!! 
No state change, as there is no transition 
which has current state (SECOND) as source 
and STEP_EVENT as transition event, 
and no eventNotAccepted call. 
But I need it, I want to fail here! */

stateMachine.sendEvent(EXIT_EVENT); 
// state will move to EXIT

问题是,当我发送一个属于配置一部分但不适用于当前状态的事件时,没有任何反应。

我不知道状态没有改变是因为守卫还是因为当前状态和我的事件没有转换。

有什么办法可以处理这种情况吗?

最佳答案

要记录不适用于您当前状态的事件,您可以使用 StateMachine 监听器。每次在状态机中传递不满足定义的转换和事件的事件时,都会调用一个方法。

在状态机配置中,您需要覆盖:

public void configure(StateMachineConfigurationConfigurer<State, Event> config) {
  config.withConfiguration()
     .listener(customListener());
}

并实现您自己的监听器 - 最简单的方法是使用 StateMachineListenerAdapter并覆盖 eventNotAccepted(Message event)方法:

private StateMachineListenerAdapter<State, Event> customListener() {
  return new StateMachineEventListenerAdapter<State, Event>() {

    @Override
    public void eventNotAccepted(Message event) {
      //LOG which event was not accepted etc.
    }
  }
}

要记录守卫的结果 - 使用守卫本身的日志消息。

如果你想暴露守卫之外的原因,你可以构造一个键值对并使用StateMachine的扩展上下文来记录守卫名称和事件被拒绝的原因。 上下文可用于构造自定义异常或向调用者代码传达发生的情况。

关于java - 如何处理spring状态机未处理的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53934031/

相关文章:

java - 设置值后 SharedPreferences 返回默认值

spring xml文件和导入xml文件循环依赖

java - ServiceActivator 'randomly' 取消订阅 PublishSubscribeChannel

spring-boot - 用于休息服务请求的 Spring 状态机配置

java - -XX :+PrintTenuringDistribution not printing the tenuring age

Java android Linearlayout设置两种颜色

java - 有没有办法将其转换为 "while loop"或 "do while loop"?

Java GET 返回日期为 13 位数字

Spring 状态机: How to get information that transition is not possible?

java - 未调用 join 后的 Spring Statemachine 内部转换操作