摘要:Spring StateMachine 是一个基于 Spring 框架的状态机实现,用于管理复杂的状态转换逻辑。以下是对其核心概念、配置方法及实际应用的详细说明:
Spring StateMachine 是一个基于 Spring 框架的状态机实现,用于管理复杂的状态转换逻辑。以下是对其核心概念、配置方法及实际应用的详细说明:
一、核心概念
状态(State)Ø 定义对象的生命周期阶段(如订单的 新建、待支付、已支付、取消)。
Ø 支持层次化状态(子状态)和并行状态(分叉/合并)。
事件(Event)Ø 触发状态转换的动作(如 支付事件、取消事件)。
转换(Transition)Ø 状态之间的流转规则,分为:
外部转换:状态变化并触发动作。
内部转换:状态不变,但触发动作。
4.守卫(Guard)
Ø 转换前的条件检查(如检查用户权限或订单金额)。
动作(Action)Ø 状态转换时执行的业务逻辑(如发送通知、更新数据库)。
二、配置 Spring StateMachine
1. 依赖引入
xml
org.springframework.statemachine
spring-statemachine-starter
3.2.0
2. 定义状态与事件
java
public enum States {
INITIAL, NEW, PAYMENT_PENDING, PAID, CANCELLED
}
public enum Events {
CREATE, PAY, CANCEL
}
3. 配置状态机
java
@Configuration
@EnableStateMachine
public class StateMachineConfig extends StateMachineConfigurerAdapter {
@Override
public void configure(StateMachineStateConfigurer states) throws Exception {
states
.withStates
.initial(States.INITIAL)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer transitions) throws Exception {
transitions
.withExternal
.source(States.INITIAL).target(States.NEW)
.event(Events.CREATE)
.and
.withExternal
.source(States.NEW).target(States.PAYMENT_PENDING)
.event(Events.PAY)
.guard(checkOrderAmountGuard) // 守卫条件
.and
.withExternal
.source(States.PAYMENT_PENDING).target(States.PAID)
.action(paymentAction); // 执行动作
}
@Bean
public Guard checkOrderAmountGuard {
return context -> {
Order order = context.getExtendedState.get("order", Order.class);
return order.getAmount > 0;
};
}
@Bean
public Action paymentAction {
return context -> {
Order order = context.getExtendedState.get("order", Order.class);
paymentService.processPayment(order);
};
}
}
三、使用状态机
1. 注入状态机并触发事件
java
@Service
public class OrderService {
@Autowired
private StateMachine stateMachine;
public void createOrder(Order order) {
stateMachine.getExtendedState.getVariables.put("order", order);
stateMachine.sendEvent(Events.CREATE);
}
public void payOrder(Order order) {
stateMachine.sendEvent(Events.PAY);
}
}
2. 监听状态变化
java
@Configuration
public class StateMachineListenerConfig {
@Bean
public StateMachineListener listener {
return new StateMachineListenerAdapter {
@Override
public void stateChanged(State from, State to) {
System.out.println("状态变更: " + from + " -> " + to);
}
};
}
}
四、高级功能
持久化状态Ø 使用 StateMachinePersister 将状态保存到数据库或 Redis。
java
@Autowired
private StateMachinePersister persister;
public void persist(String orderId) {
persister.persist(stateMachine, orderId);
}
分布式支持Ø 结合消息队列(如 RabbitMQ)实现跨服务的状态同步。
测试Ø 使用 StateMachineTestPlan 验证状态转换逻辑。
java
@Test
public void testStateTransition {
StateMachineTestPlan plan =
StateMachineTestPlanBuilder.builder
.defaultAwaitTime(2)
.stateMachine(stateMachine)
.step.expectState(States.INITIAL).and
.step.sendEvent(Events.CREATE).expectState(States.NEW).and
.build;
plan.test;
}
五、典型应用场景
订单流程管理Ø 处理订单状态的流转(创建、支付、发货、退款)。
审批工作流Ø 定义多级审批的状态跳转(提交、审核、通过/驳回)。
游戏状态控制Ø 管理游戏角色的行为状态(空闲、攻击、防御、死亡)。
六、常见问题
问题1:事件未触发转换检查守卫条件是否返回 true,或事件是否绑定到正确的源状态。问题2:状态机线程安全
确保每个状态机实例仅被单个线程使用,或在并发场景中正确同步。问题3:持久化恢复失败
验证序列化/反序列化逻辑,确保存储的上下文数据完整。
通过以上步骤,可以高效利用 Spring StateMachine 管理复杂状态逻辑,减少硬编码的条件判断,提升代码可维护性。更多细节可参考 官方文档。
来源:老客数据一点号