Spring-statemachine给end状态设置action

Spring-statemachine版本:当前最新的1.2.3.RELEASE版本

builder.configureStates()
    .withStates()
        .initial(generateStateName("task1", Status.INIT))
        .state(generateStateName("task1", Status.RUN))
        .end(generateStateName("task1", Status.END)); // 没有end(S state, Action<S, E) action)的方法

如上代码,我们想给end状态增加一个action,但是没有相应的api,于是我们把代码改成这样

builder.configureStates()
                .withStates()
                    .initial(generateStateName("task1", Status.INIT))
                    .state(generateStateName("task1", Status.RUN))
                    .state(generateStateName("task1", Status.END), context -> { /* do something*/ })
                    .end(generateStateName("task1", Status.END));

generateStateName方法直接拼接了一个字符串和Status枚举对象的名字:

protected String generateStateName(String taskName, Status status) {
    String stateName = taskName + "_" + status.name();
}

结果会发现从run状态进不了end状态,这是为什么呢?

调试源码后,发现org.springframework.statemachine.config.configurers.DefaultStateConfigurer在配置状态时在这里用到判断:

@Override
    public void configure(StateMachineStateBuilder<S, E> builder) throws Exception {
        // before passing state datas to builder, update structure
        // for missing parent, initial and end state infos.
        Collection<StateData<S, E>> stateDatas = new ArrayList<StateData<S, E>>();
        for (StateData<S, E> s : incomplete.values()) {
            s.setParent(parent);
            stateDatas.add(s);
            if (s.getState() == initialState) {
                s.setInitial(true);
                s.setInitialAction(initialAction);
            }
            if (s.getState() == end) { // 坑爹的判断方法
                s.setEnd(true);
            }
            if (choices.contains(s.getState())) {
                s.setPseudoStateKind(PseudoStateKind.CHOICE);
            } else if (junctions.contains(s.getState())) {
                s.setPseudoStateKind(PseudoStateKind.JUNCTION);
            } else if (forks.contains(s.getState())) {
                s.setPseudoStateKind(PseudoStateKind.FORK);
            } else if (joins.contains(s.getState())) {
                s.setPseudoStateKind(PseudoStateKind.JOIN);
            } else if (entrys.contains(s.getState())) {
                s.setPseudoStateKind(PseudoStateKind.ENTRY);
            } else if (exits.contains(s.getState())) {
                s.setPseudoStateKind(PseudoStateKind.EXIT);
            }
            if (s.getState() == history) {
                if (History.SHALLOW == historyType) {
                    s.setPseudoStateKind(PseudoStateKind.HISTORY_SHALLOW);
                } else if (History.DEEP == historyType) {
                    s.setPseudoStateKind(PseudoStateKind.HISTORY_DEEP);
                }
            }
            s.setSubmachine(submachines.get(s.getState()));
            s.setSubmachineFactory(submachinefactories.get(s.getState()));
        }
        builder.addStateData(stateDatas);
    }

在上面代码中判断状态:if (s.getState() == end),end是StateMachine < S, E > 泛型中的S,对于上面我写的demo中类型是String。调用state()和end()会生成两个"task1_end"字符串,他们用==判断是不相等的,因此不会被判断为终结状态。。。。。。。

好吧,把生成状态名字改成用一个map保存,然后返回已存在的状态名就行:

protected String generateStateName(String taskName, Status status) {
    String stateName = taskName + "_" + status.name();
    if (stateNameMap.containsKey(stateName)) {
        return stateNameMap.get(stateName);
    } else {
        stateNameMap.put(stateName, stateName);
        return stateName;
    }
}

转载于:https://www.cnblogs.com/lanhj/p/6618921.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值