我正在尝试在我的项目中使用Spring State Machine,因为有一个对象Order具有多个状态
该对象可以如下实现
public class Order {
private String id;
private Customer customer;
private OrderState state;
// Some other fields with getter and setter
}
Run Code Online (Sandbox Code Playgroud)
我介绍了OrderService,从DB获取订单,设置包括OrderState在内的一些信息,然后保存到DB.
但是我不知道如何将Spring状态机应用到这个中,是否过于复杂而无法使用这样的简单目的?
使用 Spring 状态机,我们有状态和事件。我找不到任何关于是否可以在配置期间将静态数据附加到状态的文档。
例如,如果有状态 S1 和 S2
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
states.withStates()
.initial("INIT")
.end("END")
.state("S1", null, exitAction())
.state("S2", entryAction());
}
Run Code Online (Sandbox Code Playgroud)
如果我们可以在上述配置期间附加静态数据(例如 java Map),那么它在触发的操作中可能会很有用(如上面的 entryAction 和 exitAction)
我不知道是否可以采取某种方式。
我是Spring State Machine的新手。我已经StateMachineListener为我的状态机使用了。我该如何访问StateContextin eventNotAccepted方法。
@Override
public void eventNotAccepted(Message<String> event) {
}
Run Code Online (Sandbox Code Playgroud) 我知道文档提到了“a”语句机,并进一步说明了“用于简单用例”的状态。这些示例定义了注释 @StateMachine,这对我的问题来说不是好兆头。
如果我希望每个业务流程有一个不同的 StateMachine,而不是尝试定义一个日益复杂的状态机,该怎么办?
我正在使用具有多个区域的 Spring 状态机,并且我将某些区域配置为具有 entryAction 和 exitAction。
我最近意识到,操作的回调在不同的线程中运行,有时它们直到状态转换完成后才完成。
以下是安排操作时的堆栈跟踪:
at org.springframework.statemachine.state.AbstractState.entry(AbstractState.java:208)
at org.springframework.statemachine.state.ObjectState.entry(ObjectState.java:156)
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1216)
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1161)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:971)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:944)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:1038)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949)
at org.springframework.statemachine.support.AbstractStateMachine.switchToState(AbstractStateMachine.java:841)
at org.springframework.statemachine.support.AbstractStateMachine.access$400(AbstractStateMachine.java:77)
at org.springframework.statemachine.support.AbstractStateMachine$2.transit(AbstractStateMachine.java:301)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleTriggerTrans(DefaultStateMachineExecutor.java:248)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.processTriggerQueue(DefaultStateMachineExecutor.java:395)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.access$100(DefaultStateMachineExecutor.java:61)
at org.springframework.statemachine.support.DefaultStateMachineExecutor$1.run(DefaultStateMachineExecutor.java:281)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.scheduleEventQueueProcessing(DefaultStateMachineExecutor.java:300)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.execute(DefaultStateMachineExecutor.java:144)
at org.springframework.statemachine.support.AbstractStateMachine.sendEventInternal(AbstractStateMachine.java:559)
at org.springframework.statemachine.support.AbstractStateMachine.sendEvent(AbstractStateMachine.java:211)
Run Code Online (Sandbox Code Playgroud)
为了避免竞争条件并确保功能完成后状态进入/退出操作完成sendEvent,我想使用同步任务调度程序,但我不认为有这样的事情(我必须实现我自己的) )。或者是否有其他方法可以确保我的进入/退出操作在转换后完成?
我想包含StateMachine使用StateMachineFactory. 但@EnableStateMachineFactory注释允许命名工厂。如何命名每个 Config (即扩展EnumStateMachineConfigurerAdapter)?
setMachineID否则,如果可能的话,提供一个如何在配置定义中使用该方法的示例将会很有用。
我有一个状态机
@EnableStateMachine
@Configuration
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<Status, Event> {
@Override
public void configure(StateMachineStateConfigurer<Status, Event> states) throws Exception {
states.withStates()
.initial(Status.DRAFT)
.states(EnumSet.allOf(Status.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<Status, Event> transitions) throws Exception {
transitions
.withExternal()
.target(Status.INVITATION).source(Status.DRAFT)
.event(Event.INVITED)
.guard(new Guard())
.action(new ActionInvited())
.and()
.withExternal()
.target(Status.DECLINED).source(Status.INVITATION)
.event(Event.DECLINED)
.action(new ActionDeclined());
}
@Override
public void configure(StateMachineConfigurationConfigurer<Status, Event> config) throws Exception {
config.withConfiguration().autoStartup(true);
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个模型,例如Order。模型保留在 DB 中。我从数据库中提取模型,现在我的模型有一个 status Order.status == INVITATION。我想用状态机继续处理模型,但状态机的实例将开始处理初始状态DRAFT但我需要从状态INVITATION继续处理。换句话说,我想执行
stateMachine.sendEvent(MessageBuilder
.withPayload(Event.DECLINED)
.setHeader("orderId", order.id)
.build()
)
Run Code Online (Sandbox Code Playgroud)
并执行操作 …