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;
}
}

Spring-statemachine给end状态设置action的更多相关文章

  1. 因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 。。。

    因为相同类型的其他实体已具有相同的主键值.在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified&quo ...

  2. (转)Spring Bean Scope 有状态的Bean 无状态的Bean

    有状态会话bean   :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”:一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束.即每个用户最初都会得到一 ...

  3. 前端技术之:如何在vuex状态管理action异步调用结束后执行UI中的方法

    一.问题的起源 最近在做vue.js项目时,遇到了vuex状态管理action与vue.js方法互相通信.互操作的问题.场景如下图所示: 二.第一种解决方法 例如,我们在页面初始化的时候,需要从服务端 ...

  4. Eureka心跳健康检查机制和Spring boot admin 节点状态一直为DOWN的排查(忽略某一个节点的健康检查)

    https://www.jdon.com/springcloud/eureka-health-monitoring.html 运行阶段执行健康检查的目的是为了从Eureka服务器注册表中识别并删除不可 ...

  5. 使用Spring StateMachine框架实现状态机

    spring statemachine刚出来不久,但是对于一些企业的大型应用的使用还是十分有借鉴意义的. 最近使用了下这个,感觉还是挺好的. 下面举个例子来说下吧: 创建一个Spring Boot的基 ...

  6. struts2 笔记01 登录、常用配置参数、Action访问Servlet API 和设置Action中对象的值、命名空间和乱码处理、Action中包含多个方法如何调用

    Struts2登录 1. 需要注意:Struts2需要运行在JRE1.5及以上版本 2. 在web.xml配置文件中,配置StrutsPrepareAndExecuteFilter或FilterDis ...

  7. tableview 编辑状态设置

    #pragma mark - tableview 编辑状态设置 -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSI ...

  8. Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

    Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx" ...

  9. Spring MVC 程序首页的设置 - 一号门-程序员的工作,程序员的生活(java,python,delphi实战)

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

随机推荐

  1. 【原创】Unable to read TLD "META-INF/c.tld" from JAR file 解决方法

    type Exception report message description The server encountered an internal error () that prevented ...

  2. 关于PY的推导式

    列表推导式: In [26]: [i*2 for i in range(10)] Out[26]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 字典推导式: In [29] ...

  3. go语言简单的执行shell命令

    package main import(     "fmt"     "os/exec"     "os"     "string ...

  4. list 分页

    package com.jsz.peini.common.util; import java.util.ArrayList; import java.util.List; public class S ...

  5. WebLogic 服务器配置

    环境版本    Windows 8.1       WebLogic 10.3.0     JDK:1.6 WebLogic 创建域在Windows环境下有两种方式: 1.直接在开始菜单创建domai ...

  6. 2016 10 26考试 NOIP模拟赛 杂题

    Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...

  7. ETL工具-informatica产品部分功能、接口采购梳理

    在项目中,经常遇到要进行产品采购,虽然一直在使用informatica工具做数据的抽取.清晰转换.加载,但是使用的功能也比较初级.在遇到采购时大致的进行了梳理. 序号 名称 产品功能说明 产品选配说明 ...

  8. 最多包含2/k个不同字符的最长串

    看这里的解答: http://www.cnblogs.com/grandyang/p/5351347.html 通用解决了2和k的问题.

  9. Redit集群搭建-Sentinel模式搭建

    Redit集群搭建 学习了: Windows:http://blog.csdn.net/mrxiagc/article/details/52799081 Linux:https://www.cnblo ...

  10. C++归并排序总结

    #include <iostream> using namespace std; //归并排序非递归版. void Sort(int a[], int n,int high) { int ...