Spring State Machine:能否从当前状态获取可用事件列表?
如何从Spring State Machine当前状态获取可用事件列表
当然可以啦!要拿到当前状态下能触发的所有可用事件,核心是从状态机的当前State对象里提取关联的转移信息——毕竟每个状态转移都是由特定事件触发的。
结合你给出的代码,我给你扩展出完整的实现示例:
首先,先获取当前状态:
StateMachine<State, Event> stateMachine = stateMachineService.acquireStateMachine(machineId); stateMachine.sendEvent(event); // 获取当前状态对象 State<State, Event> currentState = stateMachine.getState();
接下来,从当前状态中提取可用事件:
Set<Event> availableEvents = new HashSet<>(); if (currentState != null) { // 遍历当前状态的所有出向转移 for (Transition<State, Event> transition : currentState.getTransitions()) { Trigger<State, Event> trigger = transition.getTrigger(); // 只处理基于事件触发的转移 if (trigger instanceof EventTrigger) { Event availableEvent = ((EventTrigger<State, Event>) trigger).getEvent(); availableEvents.add(availableEvent); } } } // 输出可用事件,或者根据业务需求使用 availableEvents.forEach(System.out::println);
额外处理:复合状态的情况
如果你的状态机使用了复合状态(包含子状态的父状态),只取当前状态的转移可能不够,因为子状态也可能有自己的可用事件。这时候可以获取所有活跃状态(包括子状态)来提取事件:
Set<Event> availableEvents = new HashSet<>(); if (currentState != null) { // 获取所有处于活跃状态的节点(父状态+子状态) Collection<State<State, Event>> activeStates = currentState.getStates(); for (State<State, Event> state : activeStates) { for (Transition<State, Event> transition : state.getTransitions()) { Trigger<State, Event> trigger = transition.getTrigger(); if (trigger instanceof EventTrigger) { availableEvents.add(((EventTrigger<State, Event>) trigger).getEvent()); } } } }
小提示
- 要确保状态机已经完成初始化,
getState()不会返回null; - 如果你的转移设置了守卫(Guard),上面的方法会列出所有关联事件,但实际能否触发还要看守卫条件是否满足。如果需要过滤掉守卫不通过的事件,可以额外调用
guard.evaluate(StateContext)来判断是否加入可用事件列表。
内容的提问来源于stack exchange,提问作者Evghenii Orenciuc
相关产品推荐
相关产品推荐

