Java 访问bean时执行Spring状态机操作会导致状态机终止

Java 访问bean时执行Spring状态机操作会导致状态机终止,java,spring,spring-statemachine,Java,Spring,Spring Statemachine,我正在尝试创建一个状态机,它将通过一系列状态触发特定状态的进入操作,并与状态转换拦截器相结合 为了测试这个状态机,我创建了一个springboot集成测试,它向一个集成通道提供一条消息,该通道反过来调用这个状态机。我注意到的是,当操作发生时,当它开始与“存储库”bean交互时,它将导致状态机退出,集成测试失败。我在日志中没有看到任何错误,但是当我引入“error”操作时,状态机操作的行为与预期的一样 我曾尝试将断点应用于拦截器,但我注意到,当测试由于断点而停止时,在到达repository.sa

我正在尝试创建一个状态机,它将通过一系列状态触发特定状态的进入操作,并与状态转换拦截器相结合

为了测试这个状态机,我创建了一个springboot集成测试,它向一个集成通道提供一条消息,该通道反过来调用这个状态机。我注意到的是,当操作发生时,当它开始与“存储库”bean交互时,它将导致状态机退出,集成测试失败。我在日志中没有看到任何错误,但是当我引入“error”操作时,状态机操作的行为与预期的一样

我曾尝试将断点应用于拦截器,但我注意到,当测试由于断点而停止时,在到达repository.save(entity)行时,它将允许测试向前移动,就像我在断点上点击play一样,但调试器本身在操作中保持不变

当我引入errorAction()时,状态机将正常工作。我真的不知道为什么错误操作会导致机器正常完成

配置如下

@Configuration
@EnableStateMachineFactory
public class NotificationStateMachineConfiguration
    extends StateMachineConfigurerAdapter<NotificationState, NotificationEvent> {
  private static final Logger LOGGER =
      LoggerFactory.getLogger(NotificationStateMachineConfiguration.class);

  @Autowired
  private SendingAction sendingAction;
  @Autowired
  private TransformationAction transformationAction;

  @Override
  public void configure(
      StateMachineConfigurationConfigurer<NotificationState, NotificationEvent> config)
      throws Exception {
    config.withConfiguration()
        .autoStartup(false)
        .taskExecutor(new SyncTaskExecutor())
        .listener(new StateMachineListenerAdapter<NotificationState, NotificationEvent>() {
          @Override
          public void stateChanged(State<NotificationState, NotificationEvent> from,
                                   State<NotificationState, NotificationEvent> to) {
            LOGGER.trace("StateChanged - From: {}, To: {}", from, to);

          }
        });
  }

  @Override
  public void configure(
      StateMachineStateConfigurer<NotificationState, NotificationEvent> states) throws Exception {
    states.withStates()
        .initial(NotificationState.NEW)
        .state(NotificationState.NEW)
        .state(NotificationState.TRANSFORMING,transformationAction,errorAction())
        .state(NotificationState.TRANSFORMATION_FAILED)
        .state(NotificationState.SENDING,sendingAction, errorAction())
        .state(NotificationState.STAGED)
        .state(NotificationState.AWAITING)
        .end(NotificationState.NOT_SENT)
        .end(NotificationState.RESPONSE_RECEIVED)
        .end(NotificationState.ERRORS)
        .end(NotificationState.NEGATIVE_RESPONCE_RECIEVED)
        .end(NotificationState.SENT);
  }

  @Override
  public void configure(
      StateMachineTransitionConfigurer<NotificationState, NotificationEvent> transitions)
      throws Exception {
    transitions
        .withExternal()
        .source(NotificationState.NEW).target(NotificationState.TRANSFORMING)
        .event(NotificationEvent.TRANSFORMATION_REQUESTED)
        .and()
        .withExternal()
        .source(NotificationState.TRANSFORMING).target(NotificationState.SENDING)
        .event(NotificationEvent.TRANSFORMATION_SUCCESSFULL)
        .and()
        .withExternal()
        .source(NotificationState.TRANSFORMING).target(NotificationState.TRANSFORMATION_FAILED)
        .event(NotificationEvent.TRANSFORMATION_FAILURE)
        .and()
        .withExternal()
        .source(NotificationState.SENDING).target(NotificationState.AWIATING)
        .event(NotificationEvent.PROOF_OF_DELIVERY_RELEASE_REQUESTED)
        .and()
        .withExternal()
        .source(NotificationState.SENDING).target(NotificationState.SENT)
        .event(NotificationEvent.RELEASE_REQUESTED)
        .and()
        .withExternal()
        .source(NotificationState.SENDING).target(NotificationState.STAGED)
        .event(NotificationEvent.STAGE_NOTIFICATION_REQUESTED);
  }


<!-- if i remove this bean the state machine dies within the interceptor when i try to utilize the repository -->
  @Bean
  public Action<NotificationState, NotificationEvent> errorAction() {
    return context -> {
      // RuntimeException("MyError") added to context
      Exception exception = context.getException();
      LOGGER.error(Optional.ofNullable(exception).map(Exception::getMessage)
          .orElse("NO ERROR"));
    };
  }


}
@配置
@EnableStateMachineFactory
公共类通知状态机配置
扩展StateMachineConfigureAdapter{
专用静态最终记录器=
getLogger(NotificationStateMachineConfiguration.class);
@自动连线
私有发送操作发送操作;
@自动连线
私人转型行动转型行动;
@凌驾
公共无效配置(
StateMachineConfiguration配置器(配置)
抛出异常{
config.withConfiguration()
.AutoStart(错误)
.taskExecutor(新的SyncTaskExecutor())
.listener(新StateMachineListenerAdapter(){
@凌驾
公共无效状态已更改(状态从,
国家(至){
trace(“StateChanged-From:{},To:{}”,From,To);
}
});
}
@凌驾
公共无效配置(
StateMachineStateConfigurer状态)引发异常{
states.with states()
.首字母(NotificationState.NEW)
.state(NotificationState.NEW)
.state(NotificationState.TRANSFORMING、transformationAction、errorAction())
.state(NotificationState.TRANSFORMATION_失败)
.state(NotificationState.SENDING、sendingAction、errorAction())
.state(NotificationState.STAGED)
.state(NotificationState.waiting)
.end(NotificationState.NOT_SENT)
.end(NotificationState.RESPONSE_已收到)
.end(NotificationState.ERRORS)
.end(NotificationState.NEGATIVE\u Response\u Received)
.end(NotificationState.SENT);
}
@凌驾
公共无效配置(
StateMachineTransitionConfigurer转换)
抛出异常{
过渡
.withExternal()
.source(NotificationState.NEW).target(NotificationState.TRANSFORMING)
.event(NotificationEvent.TRANSFORMATION_请求)
.及()
.withExternal()
.source(NotificationState.TRANSFORMING).target(NotificationState.SENDING)
.event(NotificationEvent.TRANSFORMATION_成功)
.及()
.withExternal()
.source(NotificationState.TRANSFORMING).target(NotificationState.TRANSFORMATION_失败)
.event(NotificationEvent.TRANSFORMATION_失败)
.及()
.withExternal()
.source(NotificationState.SENDING).target(NotificationState.AWIATING)
.事件(通知事件.要求提供交货证明和放行证明)
.及()
.withExternal()
.source(NotificationState.SENDING).target(NotificationState.SENT)
.event(NotificationEvent.RELEASE_请求)
.及()
.withExternal()
.source(NotificationState.SENDING).target(NotificationState.STAGED)
.事件(通知事件。请求阶段通知);
}
@豆子
公共行动{
返回上下文->{
//已将运行时异常(“MyError”)添加到上下文中
Exception=context.getException();
LOGGER.error(可选)of nullable(exception).map(exception::getMessage)
.orElse(“无错误”);
};
}
}
拦截豆



@Component
public class NotificationStateInterceptor extends
    StateMachineInterceptorAdapter<NotificationState, NotificationEvent> {

  private static final Logger logger =
      LoggerFactory.getLogger(NotificationStateInterceptor.class.getName());
  private final NotificationRepository  repository ;

  public NotificationStateInterceptor(NotificationRepository repository) {
    this.repository = eventProducrepositoryer;
  }

  /**
   * Persist the notification that just changed state.
   *
   * @param state        the notification has just changed to.
   * @param message      that triggered the state change.
   * @param transition   that was triggered during the stage change.
   * @param stateMachine that is managing the notification's state.
   */
  @Override
  public void postStateChange(
      State<NotificationState, NotificationEvent> state,
      Message<NotificationEvent> message,
      Transition<NotificationState, NotificationEvent> transition,
      StateMachine<NotificationState, NotificationEvent> stateMachine) {

    /* trigger the more descriptive version */
    this.postStateChange(state, message, transition, stateMachine, null);
  }


  /**
   * Persist the notification that just changed state.
   *
   * @param state            the notification has just changed to.
   * @param message          that triggered the state change.
   * @param transition       that was triggered during the stage change.
   * @param stateMachine     that is managing the notification's state.
   * @param rootStateMachine in the event that this is a nested state machine.
   */
  @Override
  public void postStateChange(
      State<NotificationState, NotificationEvent> state,
      Message<NotificationEvent> message,
      Transition<NotificationState, NotificationEvent> transition,
      StateMachine<NotificationState, NotificationEvent> stateMachine,
      StateMachine<NotificationState, NotificationEvent> rootStateMachine) {

    Notification notification = getNotification(stateMachine);
    if (transition.getKind() != TransitionKind.INITIAL) {
      if (notification != null) {
        logger.debug(
            "Transitioning Notification: " + notification.getId()
                + " to State: " + state.getId());
        notification.applyNewState(state.getId());
          repository.save(notification); 
      }
    }

  }


}

@组成部分
公共类NotificationStateInterceptor扩展
StateMachineInterceptor适配器{
专用静态最终记录器=
LoggerFactory.getLogger(NotificationStateInterceptor.class.getName());
私有最终通知存储库;
公共NotificationStateInterceptor(NotificationRepository存储库){
this.repository=eventProducrepositoryer;
}
/**
*保留刚刚更改状态的通知。
*
*@param状态通知刚更改为。
*@param触发状态更改的消息。
*在阶段更改期间触发的@param转换。
*@param stateMachine正在管理通知的状态。
*/
@凌驾
公共无效状态更改(
国家,,
消息消息,
过渡,,
状态机(StateMachine){
/*触发更具描述性的版本*/
this.postStateChange(状态、消息、转换、状态机、null);
}
/**
*保留刚刚更改状态的通知。
*
*@param状态通知刚更改为。
*@param触发状态更改的消息。
*在阶段更改期间触发的@param转换。
*@param stateMachine正在管理通知的状态。
*@param rootStateMachine,如果这是嵌套状态机。
*/
@凌驾
公共无效状态更改(
国家,,
消息消息,
过渡,,
状态机状态机,
状态机(根状态机){
通知