Spring Statemachine 是一个用于在 Spring 应用中实现状态机概念的框架。它提供了一种清晰的方式来管理复杂的业务状态流转,特别适用于订单、工单、审批等有明确状态生命周期模型的业务场景。
一、核心架构概览
Spring Statemachine 的架构是分层和模块化的,主要分为以下几个核心层次:
+-----------------------------------+
| Application Layer | (您的业务代码)
+-----------------------------------+
| Spring Statemachine Framework |
| +-------------------------------+ |
| | StateMachine | | (状态机实例)
| +-------------------------------+ |
| | StateMachineContext | | (状态机上下文)
| +-------------------------------+ |
| | StateMachinePersist | | (持久化)
| +-------------------------------+ |
| | StateMachineConfig | | (配置)
| +-------------------------------+ |
+-----------------------------------+
| Spring Framework | (底层支撑)
+-----------------------------------+
二、核心组件详解
1. 状态机核心接口 (StateMachine
)
这是与状态机交互的主要入口。
关键方法:
start()
: 启动状态机sendEvent(E event)
: 发送事件触发状态转换getState()
: 获取当前状态addStateListener()
: 添加状态监听器
2. 状态 (State)
代表状态机可能处于的状况。
类型:
- 初始状态 (Initial State): 状态机的起点
- 正常状态 (Normal State): 普通业务状态
- 选择状态 (Choice State): 基于条件的路径选择
- ** junction状态 (Junction State)**: 复杂条件分支
- 最终状态 (Final State): 状态机的终点
- 分叉/汇合状态 (Fork/Join State): 用于实现并行子状态机
3. 事件 (Event)
触发状态转换的信号。通常是枚举或字符串。
4. 转换 (Transition)
定义状态如何响应事件而改变。
转换类型:
- 外部转换 (External Transition): 源状态和目标状态不同
- 内部转换 (Internal Transition): 源状态和目标状态相同,执行动作但不改变状态
- 本地转换 (Local Transition): 在子状态机内部的转换
5. 守卫 (Guard)
转换的条件判断,返回 boolean
决定是否允许转换。
java
public class OrderGuard implements Guard<String, String> {
@Override
public boolean evaluate(StateContext<String, String> context) {
return context.getMessageHeader("amount") != null;
}
}
6. 动作 (Action)
在状态转换过程中执行的具体业务逻辑。
java
public class PaymentAction implements Action<String, String> {
@Override
public void execute(StateContext<String, String> context) {
// 执行支付逻辑
System.out.println("Processing payment...");
}
}
三、配置方式详解
1. 枚举配置方式(推荐)
java
public enum OrderStates {
INITIAL, PAYMENT_PENDING, PAYMENT_PROCESSING,
PAYMENT_SUCCESS, PAYMENT_FAILED, COMPLETED, CANCELLED
}
public enum OrderEvents {
SUBMIT, PROCESS_PAYMENT, PAYMENT_SUCCESS, PAYMENT_FAILED, CANCEL
}
2. 配置类示例
java
@Configuration
@EnableStateMachine
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStates, OrderEvents> {
@Override
public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states)
throws Exception {
states
.withStates()
.initial(OrderStates.INITIAL)
.state(OrderStates.PAYMENT_PENDING)
.state(OrderStates.PAYMENT_PROCESSING, paymentAction(), null) // 进入动作,退出动作
.state(OrderStates.PAYMENT_SUCCESS)
.state(OrderStates.PAYMENT_FAILED, errorAction())
.end(OrderStates.COMPLETED)
.end(OrderStates.CANCELLED);
}
@Override
public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions)
throws Exception {
transitions
.withExternal()
.source(OrderStates.INITIAL).target(OrderStates.PAYMENT_PENDING)
.event(OrderEvents.SUBMIT)
.guard(orderGuard())
.and()
.withExternal()
.source(OrderStates.PAYMENT_PENDING).target(OrderStates.PAYMENT_PROCESSING)
.event(OrderEvents.PROCESS_PAYMENT)
.action(paymentAction())
.and()
.withExternal()
.source(OrderStates.PAYMENT_PROCESSING).target(OrderStates.PAYMENT_SUCCESS)
.event(OrderEvents.PAYMENT_SUCCESS)
.action(successAction())
.and()
.withExternal()
.source(OrderStates.PAYMENT_PROCESSING).target(OrderStates.PAYMENT_FAILED)
.event(OrderEvents.PAYMENT_FAILED)
.action(failureAction());
}
@Bean
public Guard<OrderStates, OrderEvents> orderGuard() {
return new OrderGuard();
}
@Bean
public Action<OrderStates, OrderEvents> paymentAction() {
return new PaymentAction();
}
}
四、高级特性架构
1. 分层状态机 (Hierarchical State Machine)
java
@Override
public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states)
throws Exception {
states
.withStates()
.initial(OrderStates.INITIAL)
.state(OrderStates.PAYMENT_PENDING)
.state(OrderStates.PROCESSING)
.and()
.withStates()
.parent(OrderStates.PROCESSING)
.initial(OrderStates.PACKAGING)
.state(OrderStates.SHIPPING)
.state(OrderStates.DELIVERING);
}
2. 区域状态机 (Regions - 并行状态)
java
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.SI)
.state(States.S1)
.and()
.withStates()
.parent(States.S1)
.initial(States.S2)
.region("R1")
.state(States.S3)
.and()
.withStates()
.parent(States.S1)
.initial(States.S4)
.region("R2")
.state(States.S5);
}
3. 持久化架构
java
public interface StateMachinePersist<S, E, T> {
void write(StateMachineContext<S, E> context, T contextObj) throws Exception;
StateMachineContext<S, E> read(T contextObj) throws Exception;
}
// Redis持久化示例
@Bean
public RedisStateMachinePersister<String, String> redisPersister(
RedisPersistingStateMachineInterceptor<String, String> persister) {
return new RedisStateMachinePersister<>(persister);
}
五、监听器架构
提供完整的状态机生命周期监听。
java
@Component
public class OrderStateMachineListener
implements StateMachineListener<OrderStates, OrderEvents> {
@Override
public void stateChanged(State<OrderStates, OrderEvents> from,
State<OrderStates, OrderEvents> to) {
System.out.println("State changed from " + from + " to " + to);
}
@Override
public void eventNotAccepted(Message<OrderEvents> event) {
System.out.println("Event not accepted: " + event.getPayload());
}
@Override
public void transition(Transition<OrderStates, OrderEvents> transition) {
// 转换开始
}
@Override
public void transitionStarted(Transition<OrderStates, OrderEvents> transition) {
// 转换开始
}
@Override
public void transitionEnded(Transition<OrderStates, OrderEvents> transition) {
// 转换结束
}
}
六、使用示例
1. 服务层封装
java
@Service
public class OrderStateMachineService {
@Autowired
private StateMachine<OrderStates, OrderEvents> stateMachine;
@Autowired
private StateMachinePersist<OrderStates, OrderEvents, String> persister;
public boolean submitOrder(String orderId) {
stateMachine.start();
// 发送事件
boolean accepted = stateMachine.sendEvent(OrderEvents.SUBMIT);
if (accepted) {
// 持久化状态
persister.persist(stateMachine, orderId);
}
return accepted;
}
public boolean processPayment(String orderId) {
// 从持久化存储恢复状态机
stateMachine = persister.restore(stateMachine, orderId);
Message<OrderEvents> message = MessageBuilder
.withPayload(OrderEvents.PROCESS_PAYMENT)
.setHeader("orderId", orderId)
.build();
return stateMachine.sendEvent(message);
}
}
2. 控制器层
java
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderStateMachineService stateMachineService;
@PostMapping("/{orderId}/submit")
public ResponseEntity<String> submitOrder(@PathVariable String orderId) {
boolean success = stateMachineService.submitOrder(orderId);
if (success) {
return ResponseEntity.ok("Order submitted successfully");
} else {
return ResponseEntity.badRequest().body("Failed to submit order");
}
}
}
七、最佳实践
- 状态枚举化:使用枚举定义状态和事件,避免魔法字符串
- 业务逻辑分离:在Action中执行业务逻辑,保持Guard的纯净
- 异常处理:在Action中妥善处理异常,避免状态机卡住
- 持久化策略:根据业务需求选择合适的持久化方案
- 监控和日志:充分利用监听器进行状态流转的监控和审计
- 测试策略:编写状态机的单元测试和集成测试
Spring Statemachine 通过这种清晰的架构,将复杂的状态流转逻辑可视化、可配置化,大大提高了代码的可维护性和业务的清晰度。