@Componentpublic class SaveGuard implements Guard<State, Event> {@Overridepublic boolean evaluate(StateContext<State, Event> context) {log.info("[execute save guard]");return true;}}@Componentpublic class SaveAction implements Action<State, Event> {@Overridepublic void execute(StateContext<State, Event> context) {try {log.info("[execute saveAction]");} catch (Exception e) {context.getExtendedState().getVariables().put("ERROR", e.getMessage());}}}
说明:- Guard 门卫,条件判断返回true时再执行状态转移,可以做业务前置校验 。
@Componentpublic class ActivityStateMachinePersister extends AbstractStateMachineRuntimePersister<State, Event, String> {@Autowiredprivate ActivityStateService activityStateService;@Overridepublic void write(StateMachineContext<State, Event> context, String id) {Activity state = new Activity();state.setMachineId(id);state.setState(context.getState());activityStateService.save(state);}@Overridepublic StateMachineContext<State, Event> read(String id) {return deserialize(activityStateService.getContextById(id));}}
说明:- AbstractStateMachineRuntimePersister 继承AbstractPersistingStateMachineInterceptor 并实现了StateMachineRuntimePersister接口,AbstractPersistingStateMachineInterceptor主要拦截状态变更时的状态监听 。不同于StateMachineListener被动监听,interceptor拥有可以改变状态变化链的能力 。
- 序列化存储实现参考了spring-statemachine-data-redis的实现 。
@Servicepublic class StateTransitService {@Autowiredprivate StateMachineService<State, Event> stateMachineService;@Transactionalpublic void transimit(String machineId, Message<Event> message) {StateMachine<State, Event> stateMachine = stateMachineService.acquireStateMachine(machineId);stateMachine.addStateListener(new DefaultStateMachineListener<>(stateMachine));stateMachine.sendEvent(message);if (stateMachine.hasStateMachineError()) {String errorMessage = stateMachine.getExtendedState().get("message", String.class);stateMachineService.releaseStateMachine(machineId);throw new ResponseException(errorMessage);}}}@AllArgsConstructorpublic class DefaultStateMachineListener<S, E> extends StateMachineListenerAdapter<S, E> {private final StateMachine<S, E> stateMachine;@Overridepublic void eventNotAccepted(Message<E> event) {stateMachine.getExtendedState().getVariables().put("message", "当前状态不满足执行条件");stateMachine.setStateMachineError(new ResponseException(500, "Event not accepted"));}@Overridepublic void transitionEnded(Transition<S, E> transition) {log.info("source {} to {}", transition.getSource().getId(), transition.getTarget().getId());}}
说明:- Message为发送事件的载体,其内部封装了消息体、事件等上下文扩展参数 。
- StateMachineListenerAdapter为默认监听接口的空实现,依据业务需要重写监听的方法 。
- eventNotAccepted此为事件未正确执行时的监听器 。
@SpringBootTest@RunWith(SpringRunner.class)public class StateMachineITest {@Autowiredprivate StateTransitService transmitService;@Autowiredprivate ActivityStateService activityStateService;@Testpublic void test() {String machineId = "test";//业务主键IDtransmitService.transimit(machineId, MessageBuilder.withPayload(Event.SAVE).build());transmitService.transimit(machineId, MessageBuilder.withPayload(Event.SUBMIT).build());transmitService.transimit(machineId, MessageBuilder.withPayload(Event.PASS).build());transmitService.transimit(machineId, MessageBuilder.withPayload(Event.ONLINE).build());transmitService.transimit(machineId, MessageBuilder.withPayload(Event.ONLINE).build());transmitService.transimit(machineId, MessageBuilder.withPayload(Event.OFFLINE).build());assert activityStateService.getStateById(machineId).equals(State.FINISHED);}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SpringBoot整合RocketMQ,老鸟们都是这么玩的!
- Spring注解@After,@Around,@Before的执行顺序?
- Spring Boot+Nacos+gRPC,一个区别于 OpenFeign 的微服务通信方案!
- 冬天酵母粉怎样发面快
- 不支持随机播放等,关于苹果古典乐应用 Apple Music Classical 的一些注意事项
- 在 SpringBoot 中使用 Spring AOP 实现接口鉴权
- 这两个强大的开源C#反编译逆向工具,探索C#桌面应用的秘密
- HTTP缓存如何提高Web应用程序的性能?
- 硝化细菌胶囊怎么用
- |滑漂钓鱼的4个应用场景,大鱼的克星,针对特殊鱼情的杀手锏