Spring Statemachine简记-基础配置(二)

作者: 78240024406c | 来源:发表于2018-05-17 14:37 被阅读90次

    new無语 转载请注明原创出处,谢谢!

    配置状态

    状态机最基础的状态设定。后面会介绍更复杂的配置示例,但我们首先从简单的事情开始。对于最简单的状态机,你只需使用·EnumStateMachineConfigurerAdapter·并定义可能的状态,选择初始和可选结束状态。

    枚举状态
    @Configuration
    @EnableStateMachine
    public class Config1Enums
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineStateConfigurer<States, Events> states)
                throws Exception {
            states
                .withStates()
                    //初始状态
                    .initial(States.S1)
                    //结束状态
                    .end(States.SF)
                    .states(EnumSet.allOf(States.class));
        }
    }
    
    字符串状态
    @Configuration
    @EnableStateMachine
    public class Config1Strings
            extends StateMachineConfigurerAdapter<String, String> {
    
        @Override
        public void configure(StateMachineStateConfigurer<String, String> states)
                throws Exception {
            states
                .withStates()
                    .initial("S1")
                    .end("SF")
                    .states(new HashSet<String>(Arrays.asList("S1","S2","S3","S4")));
        }
    }
    

    分层状态

    可以使用多个withStates() 调用来定义分层状态,其中parent()可以用来指示这些特定状态是某个其他状态的子状态。
    state() states() 当前层次定义状态集,任何初始状态不能在非当前层次定义。

    @Configuration
    @EnableStateMachine
    public class Config2
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineStateConfigurer<States, Events> states)
                throws Exception {
            states
                .withStates()
                    .initial(States.S1)
                    .state(States.S1)
                    .and()
                    .withStates()
                        .parent(States.S1)
                        .initial(States.S2)
                        .state(States.S2);
        }
    
    }
    

    转换状态配置

    支持三种不同类型的转换externalinternallocal

    @Configuration
    @EnableStateMachine
    public class Config3
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineStateConfigurer<States, Events> states)
                throws Exception {
            states
                .withStates()
                    .initial(States.S1)
                    .states(EnumSet.allOf(States.class));
        }
    
        @Override
        public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
                throws Exception {
            transitions
                .withExternal()
                    .source(States.S1).target(States.S2)
                    .event(Events.E1)
                    .and()
                .withInternal()
                    .source(States.S2)
                    .event(Events.E2)
                    .and()
                .withLocal()
                    .source(States.S2).target(States.S3)
                    .event(Events.E3);
        }
    
    }
    

    保护状态转换

    Guards被用来保护状态转换。

    @Configuration
    @EnableStateMachine
    public class Config4
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
                throws Exception {
            transitions
                .withExternal()
                    .source(States.S1).target(States.S2)
                    .event(Events.E1)
                    .guard(guard())
                    .and()
                .withExternal()
                    .source(States.S2).target(States.S3)
                    .event(Events.E2)
                    .guardExpression("true");
    
        }
    
        @Bean
        public Guard<States, Events> guard() {
            return new Guard<States, Events>() {
    
                @Override
                public boolean evaluate(StateContext<States, Events> context) {
                    return true;
                }
            };
        }
    
    }
    

    在上面使用了两种不同类型的防护结构。首先一个简单的Guard被创建为一个bean并添加到状态S1和状态之间的转换S2
    其次,一个简单的SPeL表达式可以用作表达式必须返回一个BOOLEAN值的校验值。在幕后,这种实现基于SpelExpressionGuard


    配置动作(actions

    actions可以定义为转换状态时同时执行的。

    @Configuration
    @EnableStateMachine
    public class Config51
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
                throws Exception {
            transitions
                .withExternal()
                    .source(States.S1)
                    .target(States.S2)
                    .event(Events.E1)
                    .action(action());
        }
    
        @Bean
        public Action<States, Events> action() {
            return new Action<States, Events>() {
    
                @Override
                public void execute(StateContext<States, Events> context) {
                    // do something
                }
            };
        }
    
    }
    

    在上面,单个action关联到状态从S1转换到S2

    @Configuration
    @EnableStateMachine
    public class Config52
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineStateConfigurer<States, Events> states)
                throws Exception {
            states
                .withStates()
                    .initial(States.S1, action())
                    .state(States.S1, action(), null)
                    .state(States.S2, null, action())
                    .state(States.S2, action())
                    .state(States.S3, action(), action());
        }
    
        @Bean
        public Action<States, Events> action() {
            return new Action<States, Events>() {
    
                @Override
                public void execute(StateContext<States, Events> context) {
                    // do something
                }
            };
        }
    
    }
    

    一般情况不会对多个状态转换做相同的action

    在上面的一个Action被关联多个状态转换。这里解释一下。

    • 定义了初始状态S1action
    • 为状态S1定义了转入动作,并且转出动作为null
    • 为状态S2定义转出行为,并将转入动作置为null
    • 为状态S2定义了一个单一行为action()
    • 为状态S3定义了转入行为以及转出行为。

    initial() 中,action()只在初始化状态时执行。state()中,action(),在转入、转出时执行。


    转换错误处理

    @Configuration
    @EnableStateMachine
    public class Config53
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
                throws Exception {
            transitions
                .withExternal()
                    .source(States.S1)
                    .target(States.S2)
                    .event(Events.E1)
                    .action(action(), errorAction());
        }
    
        @Bean
        public Action<States, Events> action() {
            return new Action<States, Events>() {
    
                @Override
                public void execute(StateContext<States, Events> context) {
                    throw new RuntimeException("MyError");
                }
            };
        }
    
        @Bean
        public Action<States, Events> errorAction() {
            return new Action<States, Events>() {
    
                @Override
                public void execute(StateContext<States, Events> context) {
                    // RuntimeException("MyError") added to context
                    Exception exception = context.getException();
                    exception.getMessage();
                }
            };
        }
    
    }
    

    动作状态异常处理

    错误处理逻辑可用于转换操作,也可用于为状态行为及其转入和转出定义的操作。

    @Configuration
    @EnableStateMachine
    public class Config55
            extends EnumStateMachineConfigurerAdapter<States, Events> {
    
        @Override
        public void configure(StateMachineStateConfigurer<States, Events> states)
                throws Exception {
            states
                .withStates()
                    .initial(States.S1)
                    .stateEntry(States.S2, action(), errorAction())
                    .stateDo(States.S2, action(), errorAction())
                    .stateExit(States.S2, action(), errorAction())
                    .state(States.S3);
        }
    
        @Bean
        public Action<States, Events> action() {
            return new Action<States, Events>() {
    
                @Override
                public void execute(StateContext<States, Events> context) {
                    throw new RuntimeException("MyError");
                }
            };
        }
    
        @Bean
        public Action<States, Events> errorAction() {
            return new Action<States, Events>() {
    
                @Override
                public void execute(StateContext<States, Events> context) {
                    // RuntimeException("MyError") added to context
                    Exception exception = context.getException();
                    exception.getMessage();
                }
            };
        }
    }
    

    相关文章

      网友评论

      本文标题:Spring Statemachine简记-基础配置(二)

      本文链接:https://www.haomeiwen.com/subject/gkpjdftx.html