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. 搭建python3环境

    将Python2.7通过控制面板卸载,然后从网站下载python的安装包,安装即可. 安装beatifulsoup4库.在命令行下, pip install beautifulsoup4 千万不能在p ...

  2. Matlab--从入门到精通(chapter2 matlab 基础知识)

    Chapter2 Matlab 基础知识 1.基本数学运算符号 注:矩阵的右除是一般意义的除法,但是左除具有对称意义,即A./B=B.\A 2. 命令行中的常用标点 3.常见的操作命令 4.输出数据显 ...

  3. 线段树(segment tree )

    http://www.cnblogs.com/TenosDoIt/p/3453089.html 写的非常好! 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很 ...

  4. laravel 5.5 项目报错

    报错内容: ErrorException (E_WARNING) Declaration of App\Observers\SiteObserver::updated($site) should be ...

  5. [LOJ2422]【NOIP2015】斗地主

    大名鼎鼎的NOIP2015D1T3 题意: 由于一些众所周知的原因,没有完整题面…… 给你一副斗地主的手牌(牌数<=23),问最少要几次能出完: 包含双王,没有癞子,连对要三连对以上,可以直接出 ...

  6. Spring boot配置404、500页面

    Spring boot 配置404页面很简单,如果你访问的url没有找到就会出现spring boot 提示的页面,很明显Spring boot不用配置就可以显示404页面了. 在template下创 ...

  7. argparse模块入门介绍——基于python3.7

    转载:https://blog.csdn.net/weixin_41796207/article/details/80846406 首先说明,本人是想要学习如何使用argparse模块,打造命令行程序 ...

  8. 四则运算1 java+jsp+SQLServer

    1,设计思想(1)在java resourse里定义包和类 (2)在类里定义生成算式,并将算式保存在数据库中的方法 (3)在jsp文件中调用java方法 2,源程序代码 生成算式的方法 public ...

  9. PatentTips - Controlling voltage and frequency

    BACKGROUND OF THE INVENTION Mobile devices, such as but not limited to personal data appliances, cel ...

  10. 基于json数据格式实现的简单数据库——jsonDB

    已在github上建立项目:https://github.com/ThinkerCodeChina/jsonDB /** +-------------------------------------- ...