如何从 Spring 状态机中获取当前子状态和父状态?

How to get the current substate and the parent state out of the Spring Statemachine?

我是 运行 一个分层的 Spring 状态机并且 - 在完成初始转换到默认子状态 STOPPED 的状态 UP 之后 - 想使用 statemachine.getState()。麻烦的是,它只给我父状态 UP,我找不到一个明显的方法来检索 both 父状态和子状态。

机器有 状态 构造如下:

    StateMachineBuilder.Builder<ToolStates, ToolEvents> builder = StateMachineBuilder.builder();


    builder.configureStates()
       .withStates()
          .initial(ToolStates.UP)
          .state(ToolStates.UP, new ToolUpEventAction(), null)
          .state(ToolStates.DOWN                
          .and()
       .withStates()
          .parent(ToolStates.UP)
          .initial(ToolStates.STOPPED)
          .state(ToolStates.STOPPED,new ToolStoppedEventAction(), null )
          .state(ToolStates.IDLE)
          .state(ToolStates.PROCESSING,
                 new ToolBeginProcessingPartAction(),
                 new ToolDoneProcessingPartAction());

    ...

    builder.build();

ToolStatesToolEvents 只是枚举。在客户端 class 中,在上面的构建器代码 运行 之后,状态机以 statemachine.start(); 启动,当我随后调用 statemachine.getState().getId(); 时,它给我 UP。在该调用之前没有事件发送到状态机。 我一直在查阅 Spring statemachine 文档和示例。我从调试中知道 UPSTOPPED 两种状态的进入操作都已被调用,因此我假设它们都是“活动的”并且希望在查询状态机时同时显示这两种状态。有没有一种干净的方法来实现这一目标?我想避免将子状态存储在 Action classes 内部的某处,因为我相信我已经首先将所有状态管理问题委托给了怪异的状态机,我更想学习如何使用它的 API 用于此目的。

希望这是一件非常明显的事情...

非常欢迎任何建议!

文档描述 getStates():

https://docs.spring.io/spring-statemachine/docs/current/api/org/springframework/statemachine/state/State.html

java.util.Collection<State<S,E>>    getStates()
Gets all possible states this state knows about including itself and substates.

stateMachine.getState().getStates();

在 SMA 最有帮助的建议之后总结:结果 stateMachine.getState().getStates(); 在我的案例中 return 包含四个元素的列表:

  • 一个 StateMachineState 实例包含 UPSTOPPED

  • 三个 ObjectState 个实例,包含 IDLESTOPPEDPROCESSING, 分别。

这让我暂时采用以下解决方案:

public List<ToolStates> getStates() {
    List<ToolStates> result = new ArrayList<>();
    Collection<State<ToolStates, ToolEvents>> states = this.stateMachine.getState().getStates();
    Iterator<State<ToolStates, ToolEvents>> iter = states.iterator();
    while (iter.hasNext()) {
        State<ToolStates, ToolEvents> candidate = iter.next();
        if (!candidate.isSimple()) {
            Collection<ToolStates> ids = candidate.getIds();
            Iterator<ToolStates> i = ids.iterator();
            while (i.hasNext()) {
                result.add(i.next());
            }
        }
    }
    return result;
}

如果使用一些流式处理和过滤,这可能会更优雅,但现在可以解决问题。不过,我不太喜欢它。这是很多 error-prone 逻辑,我必须看看它在未来是否成立 - 我想知道为什么 Spring Statemachine 中没有一个函数给我一个枚举值列表所有 当前活跃状态,而不是给予我尽一切可能并强迫我用外部逻辑来探索它...