【发布时间】:2016-02-11 02:38:23
【问题描述】:
我正在尝试将弹簧状态机的 Persist 示例扩展到两种不同的状态机配置。 http://docs.spring.io/spring-statemachine/docs/1.0.0.RELEASE/reference/htmlsingle/#statemachine-examples-persist
为此我
- 添加了新架构
- 添加了一些测试数据
- 复制了 Persist、PersistCommand 的代码并根据我的情况进行了调整
到目前为止没什么大不了的。现在进行配置:
- 我删除了 StateMachineConfig(以及 @EnableStateMachine 注释)
- 将 StateMachineConfiguration 作为 Bean 添加到 PersistHandlerConfig 中并使用 Builder
- 复制了该配置并使其适应我的用例
- 显然为我创建了一个类似 Order for my case 的类
此外,我调整了 AbstractStateMachineCommands 类并在其中自动装配状态机列表。 start/stop 和 state 方法现在启动/停止和打印每个状态机的状态(这里我不关心打印、变量)。
出现的问题是:
- 持久化不再起作用
- 我可以启动应用程序和两个状态机
- 我可以使用所有 persist 和 myUseCase 调用,但无法处理持久数据。
- 如果我例如调用persist流程1,应用程序将底层SM的状态更改为PROCESSING,但持久化的数据没有改变。
- 在调试中,我能够解决 LifecycleObjectSupport 中 getTaskExecutor 方法返回 null 的问题(而在原始示例中,bean 工厂返回 SyncTaskExecutor 的实例)。
- 此外,TestEventListener 似乎不再适用于任何状态机
- 当我在任何包含状态机 bean 的配置中使用 @EnableStateMachine 时,会在 StateMachineConfiguration 的 afterPropertiesSet 处发生 NPE。
那么,谁能告诉我我在哪里搞砸了?还是 Persist 配方不适用于两个状态机?
非常感谢。
代码示例: Application.java 现在包含这些配置和实体:
@Configuration
static class PersistHandlerConfig {
@Bean
public Persist persist() throws Exception {
return new Persist(persistStateMachineHandler());
}
@Bean
public PersistStateMachineHandler persistStateMachineHandler() throws Exception {
return new PersistStateMachineHandler(persistSm());
}
@Bean
public StateMachine<String, String> persistSm() throws Exception{
Builder<String, String> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial("PLACED")
.state("PROCESSING")
.state("SENT")
.state("DELIVERED");
builder.configureTransitions()
.withExternal()
.source("PLACED").target("PROCESSING")
.event("PROCESS")
.and()
.withExternal()
.source("PROCESSING").target("SENT")
.event("SEND")
.and()
.withExternal()
.source("SENT").target("DELIVERED")
.event("DELIVER");
return builder.build();
}
}
@Configuration
static class TicketPersistHandlerConfig {
@Bean
public TicketPersist ticketPersist() throws Exception {
return new TicketPersist(ticketPersistStateMachineHandler());
}
@Bean
public PersistStateMachineHandler ticketPersistStateMachineHandler() throws Exception {
return new PersistStateMachineHandler(buildMachine());
}
@Bean
public StateMachine<String, String> buildMachine() throws Exception {
Builder<String, String> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial("PRINTED")
.state("BOOKED")
.state("SOLD")
.state("DELIVERED");
builder.configureTransitions()
.withExternal()
.source("PRINTED").target("BOOKED")
.event("BOOK")
.and()
.withExternal()
.source("BOOKED").target("SOLD")
.event("SELL")
.and()
.withExternal()
.source("SOLD").target("DELIVERED")
.event("DELIVER");
return builder.build();
}
}
public static class Order {
int id;
String state;
public Order(int id, String state) {
this.id = id;
this.state = state;
}
@Override
public String toString() {
return "Order [id=" + id + ", state=" + state + "]";
}
}
public static class Ticket {
int id;
String state;
public Ticket(int id, String state) {
this.id = id;
this.state = state;
}
@Override
public String toString() {
return "Ticket [id=" + id + ", state=" + state + "]";
}
}
TicketPersist.java 和 TicketPersistCommands.java 与订单的相同(只是将订单替换为票证)。 我通过以下方式调整了 AbstractStateMachineCommands:
@Autowired
private List<StateMachine<S, E>> stateMachines;
@CliCommand(value = "sm start", help = "Start a state machine")
public String start() {
for (StateMachine<S, E> stateMachine : stateMachines)
{
stateMachine.start();
}
return "State machines started";
}
@CliCommand(value = "sm stop", help = "Stop a state machine")
public String stop() {
for (StateMachine<S, E> stateMachine : stateMachines)
{
stateMachine.stop();
}
return "State machines stopped";
}
【问题讨论】:
-
对于您可能面临的一些问题,有一些修复(即将发布 1.0.1)。没有看到任何代码就很难发表评论,所以如果可能的话,你介意分享一些你的东西吗?
-
嗨,我添加了一些示例代码。希望对您有所帮助。
标签: spring state-machine spring-statemachine