上一篇文章介绍了stateless4j、spring-statemachine以及squirrel-foundation三款状态机引擎的实现原理,以及我为何选择squirrel-foundation作为解决方案。本文主要介绍一下项目中如何使用squirrel-foundation的一些细节以及如何与spring进行集成。在阅读本文前,建议先阅读官方的使用手册。
squirrel-foundation状态机的使用细节
date: 2017-06-19 15:50:18
生命周期
状态机创建过程
- StateMachine: StateMachine实例由StateMachineBuilder创建不被共享,对于使用annotation方式(或fluent api)定义的StateMachine,StateMachine实例即根据此定义创建,相应的action也由本实例执行,与spring的集成最终要的就是讲spring的bean实例注入给由builder创建的状态机实例;
- StateMachineBuilder: 本质上是由StateMachineBuilderFactory创建的动态代理。被代理的StateMachineBuilder默认实现为StateMachineBuilderImpl,内部描述了状态机实例创建细节包括State、Event、Context类型信息、constructor等,同时也包含了StateMachine的一些全局共享资源包括StateConverter、EventConverter、MvelScriptManager等。StateMachineBuilder可被复用,使用中可被实现为singleton;
- StateMachineBuilderFactory: 为StateMachineBuilder创建的动态代理实例;
事件处理过程
- 状态正常迁移
TransitionBegin–(exit->transition->entry)–>TransitionComplete–>TransitionEnd - 状态迁移异常
TransitionBegin–(exit->transition->entry)–>TransitionException–>TransitionEnd - 状态迁移事件拒绝
TransitionBegin–>TransitionDeclined–>TransitionEnd
spring集成
从statemachine的生命流程上可以看到,StateMachineBuilder可以单例方式由spring container管理,而stateMachine的instance的生命周期伴随着请求(或业务)。
从这两点出发,集成spring需要完成两件事:
* (1).通过Spring创建StateMachineBuilder实例;
* (2).业务函数中通过(1)的StateMachineBuilder实例创建StateMachine实例,并向StateMachine暴露SpringApplicationContext;
泛型参数+覆盖默认构造函数隐藏StateMachineBuilder创建细节,实现ApplicationContextAware接口,接受applicationContext注入,并注入给stateMachine实例。
public abstract class AbstractStateMachineEngine<T extends UntypedStateMachine> implements ApplicationContextAware {
protected UntypedStateMachineBuilder stateMachineBuilder = null;
@SuppressWarnings(