Spring statemachine Spring状态机-如果任何操作有错误,如何导航到错误最终状态

Spring statemachine Spring状态机-如果任何操作有错误,如何导航到错误最终状态,spring-statemachine,Spring Statemachine,假设我们有3个状态S1、S3、S3和一个错误状态E1。S*状态具有分别执行A1、A2、A3的操作。如果A1、A2、A3中的任何一个导致抛出异常,则状态机应转到E1。有没有一种方法可以定义一个公共转换,即如果任何操作引发异常,请转到E1?或者我必须明确说明每个状态的转换吗 states.withStates() .initial(START) .end(END) .end(ERROR)

假设我们有3个状态S1、S3、S3和一个错误状态E1。S*状态具有分别执行A1、A2、A3的操作。如果A1、A2、A3中的任何一个导致抛出异常,则状态机应转到E1。有没有一种方法可以定义一个公共转换,即如果任何操作引发异常,请转到E1?或者我必须明确说明每个状态的转换吗

states.withStates()
                .initial(START)
                .end(END)
                .end(ERROR)
                .state(S1, A1())
                .state(S2, A2())
                .state(S3, A3())



//Is this the only way of defining error transition? Can I dry it up?
    transitions
       .withExternal()
       .source(S1)
       .event(ErrorEvent)
       .target(E1)

     .and()

        .withExternal()
           .source(S2)
           .event(ErrorEvent)
           .target(E1)

    .and()

        .withExternal()
          .source(S3)
          .event(ErrorEvent)
          .target(E1)

我希望能有个办法把它弄干。如果我有10个状态,那么这样做会变得太重复。

目前没有使用状态机生成器的通用方法。 根据定义,每个状态转换都应该在配置中明确定义

这是另一个需要讨论的问题,在SM世界中,这是否是正确的方法:

如果A1、A2、A3中的任何一个导致抛出异常,则状态 机器应该转到E1

SM是应该进入错误状态,还是应该保持在相同的状态,或者恢复到以前的状态等等,这是有争议的。 我的理解是,当错误发生在任何其他状态时,有一个通用的错误状态来转换不是一个好方法

这实际上取决于您需要如何处理错误。 例如,如果希望在调用代码上发出信号或在stateMachine外部传播错误,则可以使用StateContext或SM ExtendedContext。 您可以插入一个自定义标志(例如“hasError”)和异常本身,并将其公开给调用方代码,但这并不十分优雅。应该有人在每次调用时检查该标志是否存在,并通知调用方代码(或者调用方代码本身应该检查,这很难看)

另一种方法是清除stateContext并保持相同的状态,等待一些重试逻辑启动。 或者在您的errorAction中,您可以将ErrorEvent发送给您的SM,并在SM上下文中传递所需的任何信息,我相信这是您选择的方法

无论哪种方式-所有转换都应出现在中。 该模型可以使用构建器方法创建,也可以通过编程方式创建(例如,可以更容易地遍历所有现有状态,只需定义一个到错误状态的额外转换)

@覆盖
public StateMachineModel build(){
ConfigurationData ConfigurationData=新的ConfigurationData();
Collection stateData=new ArrayList();
stateData.add(新stateData(“S1”,true));
stateData.add(新stateData(“S2”));
stateData.add(新stateData(“S3”));
stateData.add(新stateData(“ERROR_STATE”);
StatesData StatesData=新StatesData(stateData);
Collection transitionData=new ArrayList();
添加(新的过渡数据(“S1”、“S2”、“E1”);
stateData.forEach(state->{
if(state.getState()!=错误状态){
添加(新的transitionData(state.getState(),“ERROR\u state”,“ERROR\u EVENT”);
}
});
TransitionsData TransitionsData=新的TransitionsData(transitionData);
StateMachineModel StateMachineModel=新的默认StateMachineModel(配置数据,
statesData、transitionsData);
返回状态机模型;
}

我也在寻找解决此问题的方法,但没有找到任何有用的方法。我认为使用SM配置适配器是不可能的。
@Override
public StateMachineModel<String, String> build() {
    ConfigurationData<String, String> configurationData = new ConfigurationData<>();
    Collection<StateData<String, String>> stateData = new ArrayList<>();
    stateData.add(new StateData<String, String>("S1", true));
    stateData.add(new StateData<String, String>("S2"));
    stateData.add(new StateData<String, String>("S3"));
    stateData.add(new StateData<String, String>("ERROR_STATE"));
    StatesData<String, String> statesData = new StatesData<>(stateData);
    Collection<TransitionData<String, String>> transitionData = new ArrayList<>();
    transitionData.add(new TransitionData<String, String>("S1", "S2", "E1"));
    stateData.forEach(state -> {
        if (state.getState() != ERROR_STATE) {
            transitionData.add(new TransitionData<String, String>(state.getState(), "ERROR_STATE", "ERROR_EVENT"));
        }
    });
    TransitionsData<String, String> transitionsData = new TransitionsData<>(transitionData);
    StateMachineModel<String, String> stateMachineModel = new DefaultStateMachineModel<String, String>(configurationData,
            statesData, transitionsData);
    return stateMachineModel;
}