Spring boot Spring状态机:公共转换

Spring boot Spring状态机:公共转换,spring-boot,spring-statemachine,Spring Boot,Spring Statemachine,有没有办法为多个事件配置公共外部转换? i、 e 对于所有状态X、Y、Z->取消事件时取消。 其中X,Y,Z-源,取消-目标状态 对于取消状态,在所有事件上运行公共内部转换 我有20多个州要应用此转换,手动配置所有州并不方便 我正在使用EnumStateMachineConfigureAdapter和@EnableStateMachineFactory配置状态机,我的配置如下所示 @Configuration @EnableStateMachineFactory public class Con

有没有办法为多个事件配置公共外部转换? i、 e

  • 对于所有状态X、Y、Z->取消事件时取消。 其中X,Y,Z-源,取消-目标状态
  • 对于取消状态,在所有事件上运行公共内部转换
  • 我有20多个州要应用此转换,手动配置所有州并不方便

    我正在使用
    EnumStateMachineConfigureAdapter
    @EnableStateMachineFactory
    配置状态机,我的配置如下所示

    @Configuration
    @EnableStateMachineFactory
    public class ContentOnlyStateMachineConfig extends EnumStateMachineConfigurerAdapter<TaskState, WorkflowEvent> {
    
    private final Action<TaskState, WorkflowEvent> someAction;
    private final Action<TaskState, WorkflowEvent> anotherAction;
    
    @Autowired
    public ContentOnlyStateMachineConfig(
            final Action<TaskState, WorkflowEvent> someAction,
            final Action<TaskState, WorkflowEvent> anotherAction) {
        this.someAction = someAction;
        this.anotherAction = anotherAction;
    }
    
    
    
    
    @Override
    public void configure(final StateMachineStateConfigurer<TaskState, WorkflowEvent> states)
            throws Exception {
    
        states
                .withStates()
                .initial(TaskState.CONTENT)
                .end(TaskState.COMPLETE)
                .state(TaskState.CONTENT, someAction)
                .state(TaskState.COMPLETE, anotherAction);
    
    }
    
    @Override
    public void configure(
            final StateMachineTransitionConfigurer<TaskState, WorkflowEvent> transitions)
            throws Exception {
    
        transitions
                .withExternal()
                .source(TaskState.CONTENT).target(TaskState.SOME_STATE)
                .event(WorkflowEvent.EXCEPTION)
                .and()
                .withExternal()
                .source(TaskState.EXCEPTION).target(TaskState.CANCELED)
                .event(WorkflowEvent.CANCEL)
                .and()
                .withExternal()
                .source(TaskState.SOME_STATE_2).target(TaskState.SOME_STATE_1)
                .event(WorkflowEvent.SOME_EVENT_3)
                .and()
                .withExternal()
                .source(TaskState.SOME_STATE).target(TaskState.SOME_STATE_2)
                .event(WorkflowEvent.SOME_EVENT_2)
                .and()
                .withExternal()
                .source(TaskState.SOME_STATE).target(TaskState.COMPLETE)
                .event(WorkflowEvent.ADMIN_ACCEPT)
                .and()
                .withExternal()
                .source(TaskState.SOME_STATE).target(TaskState.CONTENT)
                .event(WorkflowEvent.SOME_EVENT);
    }
    }
    
    @配置
    @EnableStateMachineFactory
    公共类ContentOnlyStateMachineConfig扩展了EnumStateMachineConfigureAdapter{
    私人最终行动;
    私人最终诉讼和其他诉讼;
    @自动连线
    公共内容LystateMachineConfig(
    最后行动,
    最后行动(另一项行动){
    this.someAction=someAction;
    this.anotherAction=另一个动作;
    }
    @凌驾
    公共无效配置(最终状态MachineStateConfigurer状态)
    抛出异常{
    州
    .with states()
    .initial(TaskState.CONTENT)
    .end(TaskState.COMPLETE)
    .state(TaskState.CONTENT,someAction)
    .状态(TaskState.COMPLETE,另一个操作);
    }
    @凌驾
    公共无效配置(
    最终状态机转换配置器转换)
    抛出异常{
    过渡
    .withExternal()
    .source(TaskState.CONTENT).target(TaskState.SOME_状态)
    .event(WorkflowEvent.EXCEPTION)
    .及()
    .withExternal()
    .source(TaskState.EXCEPTION).target(TaskState.cancelled)
    .event(WorkflowEvent.CANCEL)
    .及()
    .withExternal()
    .source(TaskState.SOME_STATE_2)。target(TaskState.SOME_STATE_1)
    .event(WorkflowEvent.SOME_event_3)
    .及()
    .withExternal()
    .source(TaskState.SOME_STATE).target(TaskState.SOME_STATE_2)
    .event(WorkflowEvent.SOME_event_2)
    .及()
    .withExternal()
    .source(TaskState.SOME_STATE)。target(TaskState.COMPLETE)
    .event(WorkflowEvent.ADMIN\u接受)
    .及()
    .withExternal()
    .source(TaskState.SOME_STATE).target(TaskState.CONTENT)
    .event(WorkflowEvent.SOME_事件);
    }
    }
    
    没有快捷方式允许用户创建意大利面;)。话虽如此,如果你在纸上画的状态图看起来像意大利面条,而不是清晰的状态图,我认为你做错了什么

    把所有的东西都放在一台平板机器上很容易造成这种状态爆炸,乳清的结构本身看起来很难理解。通常这是机器设计师需要开始考虑使用嵌套子状态的时刻。若您有多个状态,其中同一事件应使机器处于同一状态,那个么在这些状态中您已经有了共享的功能


    将这些状态放入子状态将允许从它们的父状态进行一次转换。这通常是一个在机器中如何完成事情的模型。

    不支持开箱即用的方法来配置具有多个源和单个目标的转换

    需要明确地执行此操作。
    例如:

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
    
        transitions.withExternal()
        // normal transitions configuration ..
    
        // common error transitions
        for (var state : EnumSet.of(States.A, States,B, States.C)) { 
            transitions.withExternal().source(state).target(States.ERROR).event(ERROR_EVENT);
        }
    }
    
    @覆盖
    public void configure(StateMachineTransitionConfigurer转换)引发异常{
    transitions.withExternal()
    //正常转换配置。。
    //常见错误转换
    对于(var state:EnumSet.of(States.A,States,B,States.C)){
    transitions.withExternal().source(state).target(States.ERROR).event(ERROR\u event);
    }
    }
    

    (无法使用
    Stream.of()
    ,因为
    withExternal()
    会引发选中的异常。

    谢谢您的回答!我想知道:假设你有非常简单的SM-A->B->C->D,E是“有错误”的终端状态。以下逻辑-如果在任何状态(A、B、C、D)的操作中发生错误,则转换为E。有没有方法做到这一点,而不描述所有转换?假设有一个设计良好的SM,有10个状态,您希望应用相同的需求-如果有错误,转换到常见错误状态。这很容易得到意大利面条图。这意味着如何处理?我可以为此创建一个完整的问题。@HarshulPandav描述所有状态的所有转换。