在使用spring statemachine的框架 的时候,为了方便配置所有action行为
spring 提供了 @WithStateMachine 注解,具体使用如下
@WithStateMachine(id = "test1")
public class MyTransation {
@OnTransition(source = "S_INIT", target = "S1")
public boolean toState1(@EventHeaders Map headers,
ExtendedState extendedState,
StateMachine stateMachine,
Message message,
Exception e) {
System.out.println("toState1 #######################################, 当前状态" + stateMachine.getState());
throw new RuntimeException("asfa");
}
@OnTransition(source = "S1", target = "S2")
public void toState2(StateContext stateContext) {
System.out.println("trial toState2 ####################################### " + stateContext.getTarget().getId());
}
}
在使用注解的时候,这里特意去抛一个异常,场景是很常见的,在不知道哪个步骤里面,可能动作【action】会涉及到数据库存储、外部调用,往往会出现异常的情况。
其实站在使用者的角度来看,起始此时状态是不能流转成功的【案例中S_INIT -> S1理应失败】
然而,实际测试的结果有点出乎意料:
即使被注解过的方法【handler】在其内部抛出异常【或者执行异常】,并不会影响状态的正常流转。
言外之意,不能把@OnTransition注解的方法当作正常的action来使用.
原因是出现在onTransaction这个注解,spring state machine是如何处理的。
核心类:
为了一探究竟,我们看哪个地方调用了call
可以看到notifyTransition ,这个含义就是通知的意思,其语义就是一种监听行为,监听transition转换过程中发送的状态变化时候执行的操作。
那么继续查看调用栈,其实是在触发doAction的过程之后才执行的异步通知流程。此时,doAction
报错,才不会执行状态流转,而监听状态流转是不会控制状态流转的。
所以用户在使用spring stateMachine中的注解@WithStateMachine 的时候要切记,这个方法只是一种监听器行为,而不会控制状态的流转。
结论:
不能把@OnTransition注解的方法当作正常的action来使用.,官网也处理这一句话
该注解的行为于监听状态机的事件是一致的。所以,切记把它当作监听器使用,即使报错也不影响主流程的状态流转。
千万不要因为方便而随意使用。