摘要:讲讲复杂流程的需求除了上面文章里面提到的一根筋状态机流程,实际的企业应用中状态机的流程会更加复杂,而我们最常用到的就是。当然,里面还有很多其他的东西,大部分是处理复杂状态机流程的,以后有机会我们再展开讲。
1、讲讲复杂流程的需求
除了上面文章里面提到的一根筋状态机流程,实际的企业应用中状态机的流程会更加复杂,而我们最常用到的就是choice。它类似于java的if语句,作为条件判断的分支而存在,让我们先看一张图:
这张图表现的是一个表单(form)的整个状态流程:
创建初始的空白表单( BLANK_FORM)
填写(WRITE)表单,成为填充完表单(FULL_FORM)
检查(CHEKC)表单
如果是表单名(formName)不为null,表单成为待提交表单(CONFIRM_FROM)
提交(SUBMIT)表单,成为成功提交表单(SUCCESS_FORM)
检查(CHECK)表单
如果表单名为null,表单成为待处理表单(DEAL_FORM),修改formName
处理(DEAL)表单
如果表单名还是null或者里面有个“坏”字,表单状态变成废单(FAILED_FORM)
如果表单名称没问题,表单状态变成填充完表单状态(FULL_FORM),重新走流程
大家不要在意这个例子的幼稚,毕竟它还是能用简单的方式体现出流程的复杂性(这话多么的辩证统一)。它有判断分支(还有两个),还有流程的循环,还有分支判断后的直接失败和分支判断后的后续环节,后面我们会在代码中告诉大家这里面需要注意的东西。
2、代码实现
先上状态机的四件套:States,Events,Builder和EventConfig(spring statemachine还是蛮简单的,来来回回就这几样东西)
public enum ComplexFormStates {
BLANK_FORM, // 空白表单 FULL_FORM, // 填写完表单 CHECK_CHOICE,//表单校验判断 DEAL_CHOICE,//表单处理校验 DEAL_FORM,//待处理表单 CONFIRM_FORM, // 校验完表单 SUCCESS_FORM,// 成功表单 FAILED_FORM//失败表单
}
注意一点,choice判断分支本身也是一种状态,要声明出来,这里是CHECK_CHOICE和DEAL_CHOICE
public enum ComplexFormEvents {
WRITE, // 填写 CHECK,//校验 DEAL,//处理 SUBMIT // 提交
}
同样的分支事件也要声明,这里是CHECK和DEAL。
大头是MachineBuilder,这个代码就比较多,大家最好对照着上面这张图来看,会比较清晰
/**
复杂订单状态机构建器
*/
@Component
public class ComplexFormStateMachineBuilder {
private final static String MACHINEID = "complexFormMachine"; /** * 构建状态机 * * @param beanFactory * @return * @throws Exception */ public StateMachinebuild(BeanFactory beanFactory) throws Exception { StateMachineBuilder.Builder builder = StateMachineBuilder.builder(); System.out.println("构建复杂表单状态机"); builder.configureConfiguration() .withConfiguration() .machineId(MACHINEID) .beanFactory(beanFactory); builder.configureStates() .withStates() .initial(ComplexFormStates.BLANK_FORM) .choice(ComplexFormStates.CHECK_CHOICE) .choice(ComplexFormStates.DEAL_CHOICE) .states(EnumSet.allOf(ComplexFormStates.class)); builder.configureTransitions() .withExternal() .source(ComplexFormStates.BLANK_FORM).target(ComplexFormStates.FULL_FORM) .event(ComplexFormEvents.WRITE) .and() .withExternal() .source(ComplexFormStates.FULL_FORM).target(ComplexFormStates.CHECK_CHOICE) .event(ComplexFormEvents.CHECK) .and() .withChoice() .source(ComplexFormStates.CHECK_CHOICE) .first(ComplexFormStates.CONFIRM_FORM, new ComplexFormCheckChoiceGuard()) .last(ComplexFormStates.DEAL_FORM) .and() .withExternal() .source(ComplexFormStates.CONFIRM_FORM).target(ComplexFormStates.SUCCESS_FORM) .event(ComplexFormEvents.SUBMIT) .and() .withExternal() .source(ComplexFormStates.DEAL_FORM).target(ComplexFormStates.DEAL_CHOICE) .event(ComplexFormEvents.DEAL) .and() .withChoice() .source(ComplexFormStates.DEAL_CHOICE) .first(ComplexFormStates.FULL_FORM, new ComplexFormDealChoiceGuard()) .last(ComplexFormStates.FAILED_FORM); return builder.build(); }
}
这里面出现了几个新东西,要说一下:
在configureStates时,要把每个分支都要写上去,我之前写了ComplexFormStates.CHECK_CHOICE,忘了写DEAL_CHOICE,后面的choice就不执行,搞得我找了很久,大家要注意(是的,我犯的就是这种简单弱智的错误,我还找了很久)
在我们熟悉的withExternal之后,我们迎来了为choice专门准备的withChoice()和跟随它的first(),last()。这两个代表的就是分支判断时TRUE和FALSE的状态流程去处,这里面涉及到的一个问题就是,TRUE和FALSE的判断条件是什么呢,根据啥来判断呢?
Guard就承担了这个判断的功能,看名字似乎不像。它在spring statemachine本来是用来保护这个状态跳转过程的,所以用guard,但在choice里面,它就是作为判断代码而存在的,代码如下:
public class ComplexFormCheckChoiceGuard implements Guard
@Override public boolean evaluate(StateContextcontext) { boolean returnValue = false; Form form = context.getMessage().getHeaders().get("form", Form.class); if (form.formName == null) { returnValue = false; } else { returnValue = true; } return returnValue; }
}
它只implements一个方法evaluate(),返回boolean类型,所以很适合做这个判断的功能。另外一个DEAL_CHOICE的gurad代码是这样的
public class ComplexFormDealChoiceGuard implements Guard
@Override public boolean evaluate(StateContextcontext) { System.out.println("ComplexFormDealChoiceGuard!!!!!!!!!!!!!"); boolean returnValue = false; Form form = context.getMessage().getHeaders().get("form", Form.class); if ((form.formName == null)||(form.formName.indexOf("坏") > -1)) { returnValue = false; } else { returnValue = true; } System.out.println(form.toString()+" is "+returnValue); return returnValue; }
}
还有四件套的最后一个EventConfig:
@WithStateMachine(id="complexFormMachine")
public class ComplexFormEventConfig {
private Logger logger = LoggerFactory.getLogger(getClass());
/** * 当前状态BLANK_FORM */ @OnTransition(target = "BLANK_FORM") public void create() { logger.info("---空白复杂表单---"); } @OnTransition(source = "BLANK_FORM", target = "FULL_FORM") public void write(Messagemessage) { System.out.println("传递的参数:" + message.getHeaders().get("form")); logger.info("---填写完复杂表单---"); } @OnTransition(source = "FULL_FORM", target = "CHECK_CHOICE") public void check(Message message) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---校验复杂表单---"); }
//不会执行
@OnTransition(source = "CHECK_CHOICE", target = "CONFIRM_FORM") public void check2confirm(Messagemessage) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---校验表单到待提交表单(choice true)---"); }
//不会执行
@OnTransition(source = "CHECK_CHOICE", target = "DEAL_FORM") public void check2deal(Messagemessage) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---校验表单到待提交表单(choice false)---"); } @OnTransition(source = "DEAL_FORM", target = "DEAL_CHOICE") public void deal(Message message) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---处理复杂表单---"); } //不会执行 @OnTransition(source = "DEAL_CHOICE", target = "FAILED_FORM") public void deal2fail(Message message) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---处理复杂表单失败(choice false)---"); } //不会执行 @OnTransition(source = "DEAL_CHOICE", target = "FULL_FORM") public void deal2full(Message message) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---处理复杂表单到重新填写表单(choice true)---"); } /** * CONFIRM_FORM->SUCCESS_FORM 执行的动作 */ @OnTransition(source = "CONFIRM_FORM", target = "SUCCESS_FORM") public void submit(Message message) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---表单提交成功---"); }
}
这边的代码没有任何特别的地方,唯一需要需要注意的是我标注的不会执行的这几个方法。因为在choice判断的时候,从一个状态转变到另外一个状态时,是不会在eventConfig触发方法的,比如这个方法:
//不会执行
@OnTransition(source = "CHECK_CHOICE", target = "CONFIRM_FORM") public void check2confirm(Messagemessage) { System.out.println("传递的参数:" + message.getHeaders().get("form").toString()); logger.info("---校验表单到待提交表单(choice true)---"); }
我定义了如果用户从CHECK_CHOICE状态如果判断后变成CONFIRM_FORM,执行check2confirm方法,但可惜,状态的确变化了,但这个方法不会执行,只有在做判断的时候会执行ComplexFormCheckChoiceGuard的evaluate()。这就有个问题,在实际运行中,我们的确会需要在choice做出判断状态改变的时候要做些业务处理,比如表单check成功后需要通知后续人员来处理什么的,这该怎么办呢?
简单除暴第一招,直接在gurad里面处理。这种方法其实没有任何问题,因为既然判断的业务代码在这里面,我们把判断完成后需要做的事也在这里写完不就行了。但是,本着无关的业务能解耦就解耦的原则,我们还有一个办法
漂亮解耦第二招,写个action。下面介绍下这个action。
action,看这个名字就知道是要搞事情的,之前我们把业务代码都是写到eventConfig的方法里面,但其实可以不怎么干,我们完全可以在每个状态变化的时候独立写一个action,这样的话就能做到业务的互不打扰。不如下面这段:
.withChoice()
.source(ComplexFormStates.CHECK_CHOICE) .first(ComplexFormStates.CONFIRM_FORM, new ComplexFormCheckChoiceGuard(),new ComplexFormChoiceAction()) .last(ComplexFormStates.DEAL_FORM,new ComplexFormChoiceAction()) .and()
这是builder里面的代码片段,我们直接把action插入进来,在状态变化的时候就能在action里面处理了,下面是这个action
的代码:
public class ComplexFormChoiceAction implements Action
@Override public void execute(StateContextcontext) { System.out.println("into ComplexFormChoiceAction"); Form form = context.getMessage().getHeaders().get("form", Form.class); System.out.println(form); System.out.println(context.getStateMachine().getState()); }
}
这里面只有一个execute的方法,简单明了,我们需要的参数通过context传递,其实还是message,这样的话,不同业务用不同的action就行了,我们再回头看builder里面插入action的地方:
.first(ComplexFormStates.CONFIRM_FORM, new ComplexFormCheckChoiceGuard(),new ComplexFormChoiceAction(),new ComplexFormChoiceAction())
action可以多个插入,也就是有多少多带带的业务需要在这里面处理都行,其实回过头来,不止在withChoice()里面可以,之前的withExternal()也是可以的,看代码:
.withExternal()
.source(ComplexFormStates.FULL_FORM).target(ComplexFormStates.CHECK_CHOICE) .event(ComplexFormEvents.CHECK) .action(new ComplexFormChoiceAction(),new ComplexFormChoiceAction()) .guard(new ComplexFormCheckChoiceGuard()) .and()
action可以插入多个,但guard在这里恢复了本来的作用,保护状态变化,所以只能插入一个。
3、在controller里面看结果
最后,我们还是需要看下运行的结果,我准备了三个流程:
check成功,成为SUCCESS_FORM
check失败,deal成功,回到FULL_FORM
check失败,deal失败,成为FAILED_FORM
对应的是form1,form2和form3,看代码:
@Autowired
private ComplexFormStateMachineBuilder complexFormStateMachineBuilder;
......
@RequestMapping("/testComplexFormState")
public void testComplexFormState() throws Exception { StateMachinestateMachine = complexFormStateMachineBuilder.build(beanFactory); System.out.println(stateMachine.getId()); Form form1 = new Form(); form1.setId("111"); form1.setFormName(null); Form form2 = new Form(); form2.setId("222"); form2.setFormName("好的表单"); Form form3 = new Form(); form3.setId("333"); form3.setFormName(null); // 创建流程 System.out.println("-------------------form1------------------"); stateMachine.start(); Message message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form1).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form1).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form1).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form1).build(); stateMachine.sendEvent(message); System.out.println("最终状态:" + stateMachine.getState().getId()); System.out.println("-------------------form2------------------"); stateMachine = complexFormStateMachineBuilder.build(beanFactory); stateMachine.start(); message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form2).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form2).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form2).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form2).build(); stateMachine.sendEvent(message); System.out.println("最终状态:" + stateMachine.getState().getId()); System.out.println("-------------------form3------------------"); stateMachine = complexFormStateMachineBuilder.build(beanFactory); stateMachine.start(); message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form3).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form3).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); form3.setFormName("好的表单"); message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form3).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form3).build(); stateMachine.sendEvent(message); message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form3).build(); stateMachine.sendEvent(message); System.out.println("当前状态:" + stateMachine.getState().getId()); message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form3).build(); stateMachine.sendEvent(message); System.out.println("最终状态:" + stateMachine.getState().getId()); }
......
看console的结果就知道正确与否
构建复杂表单状态机
complexFormMachine
-------------------form1------------------
2019-05-13 18:07:19.364 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白复杂表单---
2019-05-13 18:07:19.368 INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@16603576
2019-05-13 18:07:19.369 INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport : started CONFIRM_FORM BLANK_FORM FAILED_FORM FULL_FORM SUCCESS_FORM DEAL_FORM DEAL_CHOICE CHECK_CHOICE / BLANK_FORM / uuid=2aa87c74-dd28-4790-9722-d04657eaf046 / id=complexFormMachine
传递的参数:Form [id=111, formName=null]
2019-05-13 18:07:19.381 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填写完复杂表单---
当前状态:FULL_FORM
传递的参数:Form [id=111, formName=null]
2019-05-13 18:07:19.386 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校验复杂表单---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=111, formName=null] is false
into ComplexFormChoiceAction
Form [id=111, formName=null]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=381700599, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
当前状态:DEAL_FORM
传递的参数:Form [id=111, formName=null]
2019-05-13 18:07:19.389 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---处理复杂表单---
ComplexFormDealChoiceGuard!!!!!!!!!!!!!
Form [id=111, formName=null] is false
into ComplexFormChoiceAction
Form [id=111, formName=null]
ObjectState [getIds()=[DEAL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=980487842, toString()=AbstractState [id=DEAL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
当前状态:FAILED_FORM
最终状态:FAILED_FORM
-------------------form2------------------
构建复杂表单状态机
2019-05-13 18:07:19.394 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白复杂表单---
2019-05-13 18:07:19.394 INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@51adbaad
2019-05-13 18:07:19.394 INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport : started CONFIRM_FORM BLANK_FORM FAILED_FORM FULL_FORM SUCCESS_FORM DEAL_FORM DEAL_CHOICE CHECK_CHOICE / BLANK_FORM / uuid=fa133ea8-bf48-437e-ae35-dc7aa616a23c / id=complexFormMachine
传递的参数:Form [id=222, formName=好的表单]
2019-05-13 18:07:19.395 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填写完复杂表单---
当前状态:FULL_FORM
传递的参数:Form [id=222, formName=好的表单]
2019-05-13 18:07:19.396 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校验复杂表单---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=222, formName=好的表单] is true
into ComplexFormChoiceAction
Form [id=222, formName=好的表单]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=249611509, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
当前状态:CONFIRM_FORM
当前状态:CONFIRM_FORM
传递的参数:Form [id=222, formName=好的表单]
2019-05-13 18:07:19.399 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---表单提交成功---
最终状态:SUCCESS_FORM
-------------------form3------------------
构建复杂表单状态机
2019-05-13 18:07:19.404 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白复杂表单---
2019-05-13 18:07:19.405 INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@6f12d1a
2019-05-13 18:07:19.406 INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport : started CONFIRM_FORM BLANK_FORM FAILED_FORM FULL_FORM SUCCESS_FORM DEAL_FORM DEAL_CHOICE CHECK_CHOICE / BLANK_FORM / uuid=03e8c891-eedc-4922-811c-ab375a1e70ae / id=complexFormMachine
传递的参数:Form [id=333, formName=null]
2019-05-13 18:07:19.409 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填写完复杂表单---
当前状态:FULL_FORM
传递的参数:Form [id=333, formName=null]
2019-05-13 18:07:19.410 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校验复杂表单---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=333, formName=null] is false
into ComplexFormChoiceAction
Form [id=333, formName=null]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=608638875, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
当前状态:DEAL_FORM
传递的参数:Form [id=333, formName=好的表单]
2019-05-13 18:07:19.412 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---处理复杂表单---
ComplexFormDealChoiceGuard!!!!!!!!!!!!!
Form [id=333, formName=好的表单] is true
into ComplexFormChoiceAction
Form [id=333, formName=好的表单]
ObjectState [getIds()=[DEAL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=1203626264, toString()=AbstractState [id=DEAL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
当前状态:FULL_FORM
传递的参数:Form [id=333, formName=好的表单]
2019-05-13 18:07:19.413 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校验复杂表单---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=333, formName=好的表单] is true
into ComplexFormChoiceAction
Form [id=333, formName=好的表单]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=608638875, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
当前状态:CONFIRM_FORM
传递的参数:Form [id=333, formName=好的表单]
2019-05-13 18:07:19.415 INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---表单提交成功---
最终状态:SUCCESS_FORM
大家可以跑一下,对照状态机的流程图,看下结果。
4、继续废话
其实spring statemachine写到这里,基本上已经可以上手去做企业开发了。当然,spring statemachine里面还有很多其他的东西,大部分是处理复杂状态机流程的,以后有机会我们再展开讲。
源代码地址
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/75298.html
摘要:在实际的企业开发中,不可能所有情况都是从头到尾的按状态流程来,会有很多意外,比如历史数据,故障重启后的遗留流程,所以这种可以任意调节状态的才是我们需要的状态机。 1、伪持久化和中间段的状态机我们设想一个业务场景,就比如订单吧,我们一般的设计都会把订单状态存到订单表里面,其他的业务信息也都有表保存,而状态机的主要作用其实是规范整个订单业务流程的状态和事件,所以状态机要不要保存真的不重要,...
摘要:让我们先看下状态机的概念。下面是状态机模型中的个要素,即现态条件动作次态。因为订单和审批公文都有很多的流程,每个流程都会产生状态的变化,而且流程是这种业务的主轴,其他都是围绕这个流程和状态变化来考虑的,所以看起来蛮适合用状态机来做。 1、背景在我打算学习spring statemachine的时候,我几乎看过了所有网上的中文教程,基本上都处于浅尝辄止的阶段,有几篇讲的比较深入的,都只是...
摘要:虽然多个状态机的问题解决了,但是对于实际的企业应用而言,还是有问题。这个问题就用到了状态机的持久化,我们下一章就谈谈持久化问题。 1、多个状态机的搞法在实际的企业应用中,基本不可能只有一个状态机流程在跑,比如订单,肯定是很多个订单在运行,每个订单都有自己的订单状态机流程,但上一章的例子,大家可以试一下,当执行到一个状态时,再次刷新页面,不会有任何日志出现,当一个状态流程执行到某个状态,...
摘要:先来一个,它的主要作用就告诉状态机的初始状态应该啥样,然后把整个状态流程都用代码配置出来。继承了类,表明身份,我就是来配置状态机的初始状态,并描绘一下状态流程的全过程。 上一篇说了很多废话,这一篇就不唠叨,先跑起来 1、来个spring boot去start.spring.io新建一个springboot的项目,虽然我对spirngboot也有不少的牢骚,但作为demo的开始,还是一个...
摘要:目前为止,多个状态机和多种状态机都可以在里面实现了,下一章我们来解决下状态机和实际业务间的数据传输问题,毕竟我们不是为了让状态机自个独自玩耍,和业务数据互通有无才是企业开发的正道。 在上一章的例子中,我们实现了多个状态机并存执行,不同的订单有各自的状态机运行,但只有一种状态机,这显然不能满足实际业务的要求,比如我就遇到了订单流程和公文审批流程在同一个项目的情况,所以我们这一章讲怎么让多...
阅读 2716·2023-04-25 14:21
阅读 1150·2021-11-23 09:51
阅读 3914·2021-09-22 15:43
阅读 596·2019-08-30 15:55
阅读 1535·2019-08-29 11:28
阅读 2392·2019-08-26 11:44
阅读 1658·2019-08-23 18:15
阅读 2847·2019-08-23 16:42