不幸的是,弹簧状态机不能无状态运行。我也希望这个功能能够实现,并且状态机可以以完全外部化的状态运行。
只要解决方案是这样的:
- 在 spring 上下文中启用 spring 状态机工厂:
@Configuration
@EnableStateMachineFactory
public class DomainStateMachineFactory extends
EnumStateMachineConfigurerAdapter<States, Events> {
@Overrides...
}
- 在您的服务层处理这样的事件:
@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();
}
}
- 将域实体状态加载到状态机中由以下 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 );
}
}
}
- 监听器看起来像这样:
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 );
}
}
可以在此处找到详尽且更详细的说明: