zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
  • 相关阅读:
    【转】HEIF图片存储格式探秘
    【转】Maven项目中将配置文件打包到jar包中
    C++ 单词接龙
    vector vector int 初始化
    哈夫曼树的特点
    哈夫曼树的构造
    单链表的逆转(测试数据)
    单链表的逆转
    二叉搜索树的插入
    二叉搜索数的应用
  • 原文地址:https://www.cnblogs.com/lanhj/p/6618921.html
Copyright © 2011-2022 走看看