【问题标题】:Spring State Machine Builder with child state throws error - "Initial state not set"具有子状态的 Spring State Machine Builder 引发错误 - “未设置初始状态”
【发布时间】:2020-02-24 04:32:56
【问题描述】:

我正在尝试使用 SpringStateMachine Builder 从 yml 文件配置状态机。 它适用于状态和转换,但是当我尝试包含一些子状态时,我得到了以下异常。

org.springframework.statemachine.config.model.MalformedConfigurationException:初始状态未设置 在 org.springframework.statemachine.config.model.verifier.BaseStructureVerifier.verify(BaseStructureVerifier.java:59) ~[spring-statemachine-core-2.1.3.RELEASE.jar:2.1.3.RELEASE] 在 org.springframework.statemachine.config.model.verifier.CompositeStateMachineModelVerifier.verify(CompositeStateMachineModelVerifier.java:43) ~[spring-statemachine-core-2.1.3.RELEASE.jar:2.1.3.RELEASE] 在 org.springframework.statemachine.config.AbstractStateMachineFactory.getStateMachine(AbstractStateMachineFactory.java:173) ~[spring-statemachine-core-2.1.3.RELEASE.jar:2.1.3.RELEASE] 在 org.springframework.statemachine.config.AbstractStateMachineFactory.getStateMachine(AbstractStateMachineFactory.java:143) ~[spring-statemachine-core-2.1.3.RELEASE.jar:2.1.3.RELEASE] 在 org.springframework.statemachine.config.StateMachineBuilder$Builder.build(StateMachineBuilder.java:155) ~[spring-statemachine-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]

这是我的 yml 文件

states:
   initial: INITIAL_STEP
   end: END_STEP
   states:
      INITIAL_STEP : 
      SECOND_STEP : 
         - SECOND_STEP_ONE
         - SECOND_STEP_TWO
         - SECOND_STEP_THREE
      END_STEP :

   transList:
      -
         source: INITIAL_STEP
         target: SECOND_STEP
         event: INITIAL_STEP_UP
         action: initialAction
      -
         source: SECOND_STEP
         target: END_STEP
         event: SECOND_STEP
         action: secondAction

这是我的 Spring 状态机类

@Configuration
public class MyStateMachineEngine {
    private static Logger logger = LogManager.getLogger(MyStateMachineEngine.class);

    @Autowired
    private StateConfig stateconfig;

    @Bean(name = "authStateMachine")
    @SessionScope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    public StateMachine<String, String> buildStateEngine() {
        Builder<String, String> builder = StateMachineBuilder.builder();

        try {
            if (stateconfig != null) {

                Map<String,List<String>> stateListMap = stateconfig.getStates();
                List<TransProp> transList = stateconfig.getTransList();

                final StateConfigurer<String, String> stateConfigurer = builder.configureStates().withStates()
                        .initial(stateconfig.getInitial()).end(stateconfig.getEnd());

                stateListMap.keySet().forEach(state -> configureState(state,stateListMap.get(state), stateConfigurer));
                logger.info(transList.size());
                transList.forEach(trans -> addTransaction(builder, trans));

                builder.configureConfiguration().withConfiguration().autoStartup(true).beanFactory(null)
                        .machineId("OSTMACHINE");
            } else {
                logger.error("State initialization error please verify state config");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return builder.build();
    }

    private void configureState(String state, List<String> childStateList, StateConfigurer<String, String> stateConfigurer) {
        stateConfigurer.state(state);
        if(!childStateList.isEmpty()) {
            childStateList.forEach(childState -> stateConfigurer.parent(state).initial(childState).state(childState));
        }
    }

    private void addTransaction(Builder<String, String> builder, TransProp transProp) {
        try {
            if (null != transProp) {
                if (StringUtils.isBlank(transProp.getGuard())) {
                    builder.configureTransitions().withExternal().source(transProp.getSource())
                            .target(transProp.getTarget()).event(transProp.getEvent());
                } else {
                    builder.configureTransitions().withExternal().source(transProp.getSource())
                            .target(transProp.getTarget()).guard(new BaseGuard()).event(transProp.getEvent());
                }
            }

        } catch (Exception e) {
            logger.error("Error when configuring states ", e);
            new RuntimeException(e);
        }
    }

}

【问题讨论】:

    标签: java spring-boot state-machine spring-statemachine


    【解决方案1】:

    当我在本地系统上运行您的代码时,我发现了问题所在。结果发现问题出在您的 configureState 方法中,您已经完成了状态配置,应该是这样的:-

      private void configureState(String state, List<String> childStateList,
          StateConfigurer<String, String> stateConfigurer) {
        stateConfigurer.state(state);
        if (!childStateList.isEmpty()) {
          childStateList.forEach(childState -> {
            try {
              stateConfigurer.and().withStates().parent(state).initial(childState).state(childState);
            } catch (Exception e) {
              e.printStackTrace();
            }
          });
        }
      }
    

    更多信息可以参考Link

    【讨论】:

    • 谢谢 vakul,这正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2019-05-08
    • 2018-03-20
    • 1970-01-01
    • 2019-09-02
    • 2023-01-27
    • 1970-01-01
    相关资源
    最近更新 更多