Spring StateMachine可重用状态机实例

时间:2020-09-03 10:31:54

标签: java spring state-machine spring-statemachine

我有下图所示的弹簧状态机:

enter image description here

我希望状态机在应用程序启动时启动。之后,它应该进入重新状态,在某个时间(预定的时间)进入带有子状态的状态GetOrders(GetA,GetB和GetC)。之后,如果出现某些错误,则应将其放入错误中;否则,如果一切正常,则应进入重新状态,以等待调度程序。

这是我的配置

@Override
    public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
        config.withConfiguration()
          .autoStartup(true)
          .machineId("orderMachine");
    }

这是调度程序的方法:

@Scheduled(cron = "0 0 1 1 * *")
    public void startStateMachine() {
        
        StateMachine<States, Events> sm = factory.getStateMachine();
        sm.start();
        sm.sendEvent(Events.ReState);
    }

一切正常,但是我注意到,每次执行此方法时,正在启动的stateMachine与上一个都有不同的UUID,但Id相同。所以我认为我正在制作状态机的多个实例。是否可以重用同一状态机或不完成该过程。因为在我的情况下,大多数情况下,计算机的状态应为“重新状态”。可以将其视为等待状态。

2 个答案:

答案 0 :(得分:0)

您的状态机应该最有可能是公共的和静态的。这样一来,您可以确保计算机只有一个实例。

答案 1 :(得分:0)

尝试使用SpringStateMachineService获取状态机实例,而不是从StateMachineFactory显式检索它。您可以使用Spring提供的default实现:

@Bean
public StateMachineService<State, Event> stateMachineService(
        final StateMachineFactory<State, Event> stateMachineFactory) {
    return new DefaultStateMachineService<>(stateMachineFactory);
}

因此,您的代码将如下所示:

@Scheduled(cron = "0 0 1 1 * *")
public void startStateMachine() {
    // here we need to get stateMachineId from some storage
    stateMachineService.acquireStateMachine(stateMachineId, true)
            .sendEvent(Events.ReState);
}

在上面的代码中,您需要提供特定的状态机ID。通常,我将它们存储在数据库中,对其进行查询并为每个实例化状态机。 持久化状态机上下文不在问题范围内。参见Persisting State Machine