1

我倾向于 ssm,blow 是我的演示配置:

@Override
    public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
        config.withConfiguration()
                .autoStartup(true)
                .listener(listener());
    }

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception {
        states.withStates()
                .initial(States.S_1)
                .state(States.S_1, myAction(), null)
                .end(States.S_END)
                .states(EnumSet.allOf(States.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
        transitions
                .withExternal()
                .source(States.S_1).target(States.S_2).event(Events.E1).action(myAction());
    }

我将两个事件发送到机器,但它运行一次。

stateMachine.sendEvent(Events.E1);
stateMachine.sendEvent(Events.E1);

ssm 有状态吗,我怎样才能让它无状态运行?

我只想用它来定义我的业务流程。

4

3 回答 3

3

好吧,看起来事件E1将机器从S_1S_2。再次发送该事件不会做任何事情,因为机器已经处于状态并且不会发生S_2S_1to的转换。S_2

不确定使机器无状态是什么意思?

于 2016-09-23T10:27:02.363 回答
1

状态机是有状态的,因为目标是对保存的状态做出反应......并且事件确实改变了状态......

我认为在您的情况下,您可能不需要状态机而是“简单”服务层

于 2016-10-14T12:48:11.200 回答
0

不幸的是,弹簧状态机不能无状态运行。我也希望这个功能能够实现,并且状态机可以以完全外部化的状态运行。

只要解决方案是这样的

  1. 在 spring 上下文中启用 spring 状态机工厂:
   @Configuration
   @EnableStateMachineFactory
   public class DomainStateMachineFactory extends
      EnumStateMachineConfigurerAdapter<States, Events> {
    
    @Overrides...
   }
  1. 在您的服务层处理这样的事件:
   @Service
   public class DomainStateService {

     @Autowired
     StateMachineFactory<States, Events> stateMachineFactory;

     @Autowired
     private DomainStateMachinePersister persister;

     public StateTransitionEvaluationHolder processEvent( DomainEntity entity, Events event ) {

        // create a brand new state machine
        StateMachine<StatusDto, StatusEventDto> stateMachine = stateMachineFactory.getStateMachine();

        // load the the state of your domain entity into the state machine
        StateMachine<StatusDto, StatusEventDto> restoredStateMachine =
                persister.restore( stateMachine, entity );

        // register a state changed listener
        restoredStateMachine.addStateListener( 
            new DomainStateMachineListener( entity ) );

        // start the machine
        restoredStateMachine.startReactively().block();

        // process the event
        restoredStateMachine.sendEvent( Mono.just( MessageBuilder.withPayload( event ).build() ) )
                            .blockFirst();

        // stop the machine
        restoredStateMachine.stopReactively().block();
     }
   }
  1. 将域实体状态加载到状态机中由以下 2 个类处理:

一个)

   @Component
   public class DomainEntityPersist implements
       StateMachinePersist<States, Events, DomainEntity> {

     @Override
     public void write( StateMachineContext<States, Events> stateMachineContext,
         DomainEntity entity ) {

       throw new StateMachineException( "Persistence not supported. Persisted state remains in Domain Entity." );
     }

     @Override
     public StateMachineContext<States, Events> read( DomainEntity entity ) {

       ExtendedState extendedState = new DefaultExtendedState();
       return new DefaultStateMachineContext<>( entity.getState(), null,
                                             null, extendedState, null,
                                             DomainStateMachineFactory.MACHINE_ID );
     }
   }

b)

   @Component
   public class DomainEntityStateMachinePersister {

     DomainEntityPersist persist;

     StateMachinePersister<States, Events, DomainEntity> persister;

     public DomainEntityStateMachinePersister ( DomainEntityPersist persist ) {

       this.persist = persist;
       this.persister = new DefaultStateMachinePersister<>( persist );
     }

     public void persist( StateMachine<States, Events> stateMachine,
         DomainEntity entity ) {

       try {
         persister.persist( stateMachine, entity );
       }
       catch ( Exception e ) {
         throw new StateMachineException( e );
       }
     }

      public StateMachine<States, Events> restore(
          StateMachine<States, Events> stateMachine, DomainEntity entity ) {

        try {
          return persister.restore( stateMachine, entity );
        }
        catch ( Exception e ) {
          throw new StateMachineException( e );
        }
      }
    }
  1. 监听器看起来像这样:
    public class DomainStateMachineListener extends
        StateMachineListenerAdapter<States, Events> {

      boolean changed = false;
      DomainEntity entity;

      public DomainStateMachineListener( DomainEntity entity ) {
        this.entity = entity;
      }

      @Override
      public void stateChanged( State<Statues, Events> from,
          State<States, Events> to ) {
        entity.setState( to.getId() );
        setChanged( true );
      }
    }

可以在此处找到详尽且更详细的说明:

于 2022-01-29T10:46:17.650 回答