我正在尝试从一个uml模型创建一些状态机实例。我使用stateMachineFactory。我希望这些机器独立且异步地工作。
如果我仅使用“基本”状态,那么一切都很好。机器实例可以独立地进入stateB和StateC。但是,当我使用区域和子状态(stateD)时,机器实例一个接一个地执行动作(insideStateD1)。请查看。
我发现状态是通过stateMachineTaskExecutor(默认为SyncTaskExecutor)执行的,而子状态是通过taskScheduler(默认为ConcurrentTaskScheduler)执行的。
这是配置:
@Configuration
@EnableStateMachineFactory
public class StateMachineConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
StateMachineComponentResolver<String, String> stateMachineComponentResolver;
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
UmlStateMachineModelFactory umlStateMachineModelFactory = new UmlStateMachineModelFactory("classpath:uml/testSM1.uml");
umlStateMachineModelFactory.setStateMachineComponentResolver(stateMachineComponentResolver);
return umlStateMachineModelFactory;
}
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Override
public void configure(StateMachineConfigurationConfigurer<String, String> config) throws Exception {
config
.withConfiguration()
// .taskExecutor() // I tried various taskExecutors
// .taskScheduler() // I tried various taskSchedulers
;
}
}
从同一模型中获得许多状态机实例的正确方法是什么?
答案 0 :(得分:0)
StateMachineFactory可以获取SM的多个实例。
stateMachineFactory.getStateMachine(); //builds a new state machine
您在StateMachineConfig中创建的配置适用于所有SM实例。
Spring State Machine使用TaskExecutor
来执行区域(与顶级或嵌套区域无关),默认情况下它是同步的。要实现异步执行,您需要覆盖默认的任务执行器。这可以在配置中实现:
@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
config
.withConfiguration()
//other configs
.taskExecutor(myAsyncTaskExecutor())
}
public TaskExecutor myAsyncTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
return taskExecutor;
}
或通过声明一个bean:
@Bean(name = StateMachineSystemConstants.TASK_EXECUTOR_BEAN_NAME)
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
return taskExecutor;
}
TaskScheduler
用于执行动作(与状态或过渡相关联的动作),而不用于子状态。