状态机是软件开发中处理复杂业务流程的核心模式之一。本文将深入探讨Java中的状态机实现,从基础概念到高级应用,为你打造完整的状态机开发指南。
🎯 状态机基础概念
1. 状态机是什么?
🏗️ 状态机定义
1 2 3 4 5 6 7 8 9
| 状态机(State Machine)是一个数学模型,由以下核心组件组成:
1. **状态(State)**:对象在某个时刻的条件或状况 2. **事件(Event)**:触发状态转换的外部输入 3. **转换(Transition)**:从一个状态到另一个状态的变化过程 4. **动作(Action)**:状态转换时执行的操作 5. **守卫条件(Guard)**:控制转换是否可以发生的条件
状态机 = 状态集合 + 事件集合 + 转换规则 + 初始状态
|
📊 状态机图解
1 2 3 4 5 6 7 8 9 10 11
| stateDiagram-v2 [*] --> Draft: 创建订单 Draft --> Pending: 提交订单 Pending --> Paid: 支付成功 Pending --> Cancelled: 取消订单 Paid --> Shipped: 发货 Paid --> Refunded: 申请退款 Shipped --> Delivered: 确认收货 Delivered --> [*] Cancelled --> [*] Refunded --> [*]
|
2. 状态机分类
🎨 确定性有限自动机(DFA)
- 特点:每个状态对每个输入都有唯一的后继状态
- 优点:简单、确定性强、易于理解
- 缺点:灵活性差,无法处理复杂业务逻辑
🔄 非确定性有限自动机(NFA)
- 特点:一个状态对一个输入可以有多个后继状态
- 优点:灵活性强,可以处理复杂的业务场景
- 缺点:实现复杂,难以调试
🤖 层次状态机(Hierarchical State Machine)
- 特点:支持状态嵌套,父状态包含子状态
- 优点:可以简化复杂状态图,提高可维护性
- 缺点:设计复杂度较高
🏗️ Java状态机实现方式
1. 枚举实现简单状态机
🎯 基础枚举状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public enum OrderState { DRAFT("草稿") { @Override public OrderState next(OrderEvent event) { return switch (event) { case SUBMIT -> PENDING; case CANCEL -> CANCELLED; default -> this; }; } }, PENDING("待支付") { @Override public OrderState next(OrderEvent event) { return switch (event) { case PAY -> PAID; case CANCEL -> CANCELLED; case TIMEOUT -> CANCELLED; default -> this; }; } }, PAID("已支付") { @Override public OrderState next(OrderEvent event) { return switch (event) { case SHIP -> SHIPPED; case REFUND -> REFUNDED; default -> this; }; } }, SHIPPED("已发货") { @Override public OrderState next(OrderEvent event) { return switch (event) { case DELIVER -> DELIVERED; default -> this; }; } }, DELIVERED("已送达"), CANCELLED("已取消"), REFUNDED("已退款");
private final String description;
OrderState(String description) { this.description = description; }
public OrderState next(OrderEvent event) { return this; }
public String getDescription() { return description; } }
public enum OrderEvent { SUBMIT, PAY, CANCEL, TIMEOUT, SHIP, DELIVER, REFUND }
|
🚀 枚举状态机使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| @Service @Slf4j public class OrderService {
public Order processOrderEvent(Long orderId, OrderEvent event) { Order order = orderRepository.findById(orderId) .orElseThrow(() -> new RuntimeException("订单不存在"));
OrderState currentState = order.getState(); OrderState nextState = currentState.next(event);
if (currentState != nextState) { log.info("订单 {} 状态从 {} 变更为 {}", orderId, currentState, nextState);
executeStateTransition(order, currentState, nextState, event);
order.setState(nextState); order.setUpdatedAt(LocalDateTime.now()); orderRepository.save(order);
eventPublisher.publishEvent(new OrderStateChangedEvent(order, currentState, nextState, event)); }
return order; }
private void executeStateTransition(Order order, OrderState from, OrderState to, OrderEvent event) { switch (to) { case PAID: paymentService.confirmPayment(order); break; case SHIPPED: shippingService.createShipment(order); break; case CANCELLED: inventoryService.releaseStock(order); break; case REFUNDED: refundService.processRefund(order); break; } } }
|
2. 状态模式实现状态机
🎨 状态模式设计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| public interface OrderState { void handle(Order order, OrderEvent event); OrderStateEnum getState(); }
@Component public class PendingState implements OrderState {
@Autowired private PaymentService paymentService;
@Override public void handle(Order order, OrderEvent event) { switch (event) { case PAY: if (paymentService.processPayment(order)) { order.setState(new PaidState()); log.info("订单 {} 支付成功", order.getId()); } else { throw new PaymentException("支付失败"); } break; case CANCEL: order.setState(new CancelledState()); log.info("订单 {} 已取消", order.getId()); break; default: throw new InvalidEventException("无效事件: " + event); } }
@Override public OrderStateEnum getState() { return OrderStateEnum.PENDING; } }
@Component public class PaidState implements OrderState {
@Autowired private ShippingService shippingService;
@Override public void handle(Order order, OrderEvent event) { switch (event) { case SHIP: shippingService.createShipment(order); order.setState(new ShippedState()); log.info("订单 {} 已发货", order.getId()); break; case REFUND: order.setState(new RefundedState()); log.info("订单 {} 正在退款", order.getId()); break; default: throw new InvalidEventException("无效事件: " + event); } }
@Override public OrderStateEnum getState() { return OrderStateEnum.PAID; } }
|
🎯 状态机上下文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| @Service @Slf4j public class OrderStateMachine {
private final Map<OrderStateEnum, OrderState> stateMap;
@Autowired public OrderStateMachine(List<OrderState> states) { this.stateMap = states.stream() .collect(Collectors.toMap(OrderState::getState, Function.identity())); }
public void processEvent(Order order, OrderEvent event) { OrderState currentState = stateMap.get(order.getState()); if (currentState == null) { throw new IllegalStateException("未知状态: " + order.getState()); }
log.info("订单 {} 当前状态: {}, 处理事件: {}", order.getId(), currentState.getState(), event);
try { currentState.handle(order, event); } catch (Exception e) { log.error("处理订单事件失败: orderId={}, event={}, error={}", order.getId(), event, e.getMessage()); throw e; } }
@Async public void processEvents(List<OrderEventRequest> requests) { for (OrderEventRequest request : requests) { try { Order order = orderRepository.findById(request.getOrderId()) .orElseThrow(() -> new OrderNotFoundException(request.getOrderId()));
processEvent(order, request.getEvent()); orderRepository.save(order);
} catch (Exception e) { log.error("批量处理事件失败: {}", request, e); failedEventRepository.save(new FailedEvent(request, e)); } } } }
|
3. Spring State Machine实现
🌟 Spring State Machine配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| @Configuration @EnableStateMachine public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {
@Override public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception { states .withStates() .initial(OrderState.DRAFT) .state(OrderState.PENDING) .state(OrderState.PAID) .state(OrderState.SHIPPED) .state(OrderState.DELIVERED) .end(OrderState.CANCELLED) .end(OrderState.REFUNDED); }
@Override public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception { transitions .withExternal() .source(OrderState.DRAFT).target(OrderState.PENDING) .event(OrderEvent.SUBMIT) .action(orderSubmitAction()) .and() .withExternal() .source(OrderState.PENDING).target(OrderState.PAID) .event(OrderEvent.PAY) .action(orderPayAction()) .guard(orderPayGuard()) .and() .withExternal() .source(OrderState.PENDING).target(OrderState.CANCELLED) .event(OrderEvent.CANCEL) .action(orderCancelAction()) .and() .withExternal() .source(OrderState.PAID).target(OrderState.SHIPPED) .event(OrderEvent.SHIP) .action(orderShipAction()) .and() .withExternal() .source(OrderState.SHIPPED).target(OrderState.DELIVERED) .event(OrderEvent.DELIVER) .action(orderDeliverAction()); }
@Bean public Action<OrderState, OrderEvent> orderSubmitAction() { return context -> { Order order = (Order) context.getMessageHeader("order"); log.info("订单 {} 已提交", order.getId()); order.setSubmittedAt(LocalDateTime.now()); }; }
@Bean public Action<OrderState, OrderEvent> orderPayAction() { return context -> { Order order = (Order) context.getMessageHeader("order"); log.info("订单 {} 支付成功", order.getId()); paymentService.confirmPayment(order); }; }
@Bean public Guard<OrderState, OrderEvent> orderPayGuard() { return context -> { Order order = (Order) context.getMessageHeader("order"); return paymentService.validatePayment(order); }; } }
|
🎯 Spring State Machine使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| @Service @Slf4j public class OrderStateMachineService {
@Autowired private StateMachine<OrderState, OrderEvent> stateMachine;
@Autowired private OrderRepository orderRepository;
public void processOrderEvent(Long orderId, OrderEvent event) { Order order = orderRepository.findById(orderId) .orElseThrow(() -> new RuntimeException("订单不存在"));
stateMachine.start();
try { stateMachine.getStateMachineAccessor() .doWithAllRegions(access -> access.resetStateMachine( new DefaultStateMachineContext<>(order.getState(), null, null, null)));
Message<OrderEvent> message = MessageBuilder .withPayload(event) .setHeader("order", order) .build();
boolean success = stateMachine.sendEvent(message);
if (success) { OrderState newState = stateMachine.getState().getId(); order.setState(newState); order.setUpdatedAt(LocalDateTime.now()); orderRepository.save(order);
log.info("订单 {} 状态从 {} 变更为 {}", orderId, order.getState(), newState); } else { throw new StateMachineException("状态转换失败"); }
} finally { stateMachine.stop(); } }
@OnStateChanged public void onStateChanged(State<OrderState, OrderEvent> from, State<OrderState, OrderEvent> to) { log.info("状态从 {} 变更为 {}", from.getId(), to.getId()); }
@OnTransition public void onTransition(Transition<OrderState, OrderEvent> transition) { log.info("转换: {} -> {} via {}", transition.getSource().getId(), transition.getTarget().getId(), transition.getTrigger().getEvent()); } }
|
⚖️ 状态机的优缺点分析
1. 状态机的优点
✅ 代码结构清晰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public void processOrder(Order order, String action) { if ("submit".equals(action)) { if (order.getState() == OrderState.DRAFT) { order.setState(OrderState.PENDING); } } else if ("pay".equals(action)) { if (order.getState() == OrderState.PENDING) { order.setState(OrderState.PAID); } } }
stateMachine.processEvent(order, OrderEvent.valueOf(action.toUpperCase()));
|
✅ 业务逻辑集中
- 状态转换规则集中管理:所有状态转换逻辑在一个地方定义
- 转换动作统一处理:状态转换时的业务逻辑统一管理
- 状态变更历史可追踪:可以记录状态变迁历史
✅ 易于扩展
- 新增状态简单:只需要添加新的状态类或枚举值
- 新增事件简单:添加新事件及其处理逻辑
- 修改转换规则简单:集中修改转换配置
✅ 错误处理完善
- 无效转换检测:自动检测无效的状态转换
- 异常处理统一:统一的异常处理机制
- 回滚机制:支持状态转换失败时的回滚
2. 状态机的缺点
❌ 学习成本较高
- 概念理解复杂:需要理解状态机理论
- 框架学习曲线陡峭:Spring State Machine等框架有一定的学习成本
- 调试困难:状态机调试相对复杂
❌ 性能开销
- 对象创建开销:状态对象创建和销毁的开销
- 状态持久化开销:状态需要持久化存储
- 序列化开销:分布式环境下状态序列化开销
❌ 适用场景有限
- 不适合简单状态管理:对于简单的状态管理,使用状态机可能过于复杂
- 不适合高并发场景:状态机可能成为性能瓶颈
- 不适合无状态业务:纯函数式业务不需要状态机
🚀 事件触发机制详解
1. 同步事件触发
⚡ 直接方法调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Service public class OrderService {
@Autowired private OrderStateMachine stateMachine;
public void submitOrder(Long orderId) { Order order = orderRepository.findById(orderId) .orElseThrow(() -> new OrderNotFoundException(orderId));
stateMachine.processEvent(order, OrderEvent.SUBMIT);
sendNotification(order); } }
|
🔄 事务中触发事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Service @Transactional public class OrderService {
public void payOrder(Long orderId, PaymentInfo paymentInfo) { Order order = orderRepository.findById(orderId) .orElseThrow(() -> new OrderNotFoundException(orderId));
paymentService.validatePayment(paymentInfo);
stateMachine.processEvent(order, OrderEvent.PAY);
orderRepository.save(order);
notificationService.sendPaymentSuccessNotification(order); } }
|
2. 异步事件触发
📨 消息队列触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| @Service @Slf4j public class OrderEventProcessor {
@Autowired private OrderStateMachine stateMachine;
@Autowired private OrderEventPublisher eventPublisher;
@Async public void processEventAsync(Long orderId, OrderEvent event) { try { Order order = orderRepository.findById(orderId) .orElseThrow(() -> new OrderNotFoundException(orderId));
log.info("异步处理订单事件: orderId={}, event={}", orderId, event);
stateMachine.processEvent(order, event); orderRepository.save(order);
eventPublisher.publishOrderStateChangedEvent(order, event);
} catch (Exception e) { log.error("异步处理订单事件失败: orderId={}, event={}", orderId, event, e); eventPublisher.publishToRetryQueue(orderId, event); } }
@Async public void processEventsBatch(List<OrderEventRequest> requests) { log.info("开始批量处理 {} 个订单事件", requests.size());
List<CompletableFuture<Void>> futures = requests.stream() .map(request -> CompletableFuture.runAsync(() -> processEventAsync(request.getOrderId(), request.getEvent()))) .collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) .whenComplete((result, throwable) -> { if (throwable != null) { log.error("批量处理事件时发生错误", throwable); } else { log.info("批量处理 {} 个订单事件完成", requests.size()); } }); } }
|
📬 事件驱动架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| @Service @Slf4j public class OrderEventListener {
@Autowired private OrderStateMachine stateMachine;
@EventListener public void onPaymentSuccess(PaymentSuccessEvent event) { log.info("收到支付成功事件: {}", event.getOrderId());
try { Order order = orderRepository.findById(event.getOrderId()) .orElseThrow(() -> new OrderNotFoundException(event.getOrderId()));
stateMachine.processEvent(order, OrderEvent.PAY); orderRepository.save(order);
} catch (Exception e) { log.error("处理支付成功事件失败: {}", event.getOrderId(), e); } }
@EventListener public void onShipmentDelivered(ShipmentDeliveredEvent event) { log.info("收到发货完成事件: {}", event.getOrderId());
Order order = orderRepository.findById(event.getOrderId()) .orElseThrow(() -> new OrderNotFoundException(event.getOrderId()));
stateMachine.processEvent(order, OrderEvent.DELIVER); orderRepository.save(order); }
@Scheduled(fixedRate = 60000) public void checkTimeoutOrders() { List<Order> timeoutOrders = orderRepository.findTimeoutOrders( LocalDateTime.now().minusMinutes(30));
for (Order order : timeoutOrders) { try { log.info("处理超时订单: {}", order.getId()); stateMachine.processEvent(order, OrderEvent.TIMEOUT); orderRepository.save(order); } catch (Exception e) { log.error("处理超时订单失败: {}", order.getId(), e); } } } }
|
3. 事件触发策略
🎯 事件去重机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Service @Slf4j public class EventDeduplicationService {
@Autowired private RedisTemplate<String, String> redisTemplate;
private static final String EVENT_KEY_PREFIX = "order:event:"; private static final Duration EVENT_TTL = Duration.ofHours(24);
public boolean isEventProcessed(String eventId) { String key = EVENT_KEY_PREFIX + eventId; return Boolean.TRUE.equals(redisTemplate.hasKey(key)); }
public void markEventProcessed(String eventId) { String key = EVENT_KEY_PREFIX + eventId; redisTemplate.opsForValue().set(key, "processed", EVENT_TTL); }
public boolean processEventIfNotDuplicate(String eventId, Runnable eventProcessor) { if (isEventProcessed(eventId)) { log.warn("事件已处理,跳过: {}", eventId); return false; }
try { eventProcessor.run(); markEventProcessed(eventId); return true; } catch (Exception e) { log.error("事件处理失败: {}", eventId, e); return false; } } }
|
🔄 事件重试机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @Service @Slf4j public class EventRetryService {
@Autowired private OrderStateMachine stateMachine;
private static final int MAX_RETRY_ATTEMPTS = 3; private static final Duration RETRY_DELAY = Duration.ofSeconds(30);
@Async public void processEventWithRetry(Long orderId, OrderEvent event, int attempt) { try { log.info("尝试处理事件 (第{}次): orderId={}, event={}", attempt, orderId, event);
Order order = orderRepository.findById(orderId) .orElseThrow(() -> new OrderNotFoundException(orderId));
stateMachine.processEvent(order, event); orderRepository.save(order);
log.info("事件处理成功: orderId={}, event={}", orderId, event);
} catch (Exception e) { log.error("事件处理失败 (第{}次): orderId={}, event={}", attempt, orderId, event, e);
if (attempt < MAX_RETRY_ATTEMPTS) { scheduleRetry(orderId, event, attempt + 1); } else { alertService.sendAlert("事件处理失败", String.format( "订单 %d 事件 %s 处理失败,已达到最大重试次数", orderId, event)); } } }
@Async public void scheduleRetry(Long orderId, OrderEvent event, int attempt) { try { Thread.sleep(RETRY_DELAY.toMillis()); processEventWithRetry(orderId, event, attempt); } catch (InterruptedException e) { Thread.currentThread().interrupt(); log.error("重试调度被中断: orderId={}, event={}", orderId, event); } } }
|
🏭 实际应用案例
1. 订单流程管理
📋 电商订单状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public enum OrderState { DRAFT, PENDING_PAYMENT, PAID, PROCESSING, SHIPPED, DELIVERED, CANCELLED, REFUNDED, CLOSED }
public enum OrderEvent { CREATE, PAY, CONFIRM, SHIP, DELIVER, CANCEL, REFUND_REQUEST, REFUND_APPROVE, REFUND_REJECT, CLOSE }
|
🔄 订单状态机实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| @Configuration @EnableStateMachine public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {
@Override public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception { states .withStates() .initial(OrderState.DRAFT) .state(OrderState.PENDING_PAYMENT) .state(OrderState.PAID) .state(OrderState.PROCESSING) .state(OrderState.SHIPPED) .state(OrderState.DELIVERED) .end(OrderState.CANCELLED) .end(OrderState.REFUNDED) .end(OrderState.CLOSED); }
@Override public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception { transitions .withExternal() .source(OrderState.DRAFT).target(OrderState.PENDING_PAYMENT) .event(OrderEvent.CREATE) .action(createOrderAction()) .and() .withExternal() .source(OrderState.PENDING_PAYMENT).target(OrderState.PAID) .event(OrderEvent.PAY) .action(payOrderAction()) .guard(paymentGuard()) .and() .withExternal() .source(OrderState.PAID).target(OrderState.PROCESSING) .event(OrderEvent.CONFIRM) .action(confirmOrderAction()) .and() .withExternal() .source(OrderState.PROCESSING).target(OrderState.SHIPPED) .event(OrderEvent.SHIP) .action(shipOrderAction()) .and() .withExternal() .source(OrderState.SHIPPED).target(OrderState.DELIVERED) .event(OrderEvent.DELIVER) .action(deliverOrderAction()) .and() .withExternal() .source(OrderState.DRAFT).target(OrderState.CANCELLED) .event(OrderEvent.CANCEL) .action(cancelOrderAction()) .and() .withExternal() .source(OrderState.PENDING_PAYMENT).target(OrderState.CANCELLED) .event(OrderEvent.CANCEL) .action(cancelOrderAction()) .and() .withExternal() .source(OrderState.PAID).target(OrderState.REFUNDED) .event(OrderEvent.REFUND_REQUEST) .action(refundRequestAction()) .guard(refundGuard()) .and() .withExternal() .source(OrderState.DELIVERED).target(OrderState.REFUNDED) .event(OrderEvent.REFUND_REQUEST) .action(refundRequestAction()) .guard(refundGuard()); }
@Bean public Action<OrderState, OrderEvent> createOrderAction() { return context -> { Order order = context.getMessage().getHeaders().get("order", Order.class); order.setCreatedAt(LocalDateTime.now()); orderRepository.save(order); log.info("订单 {} 创建成功", order.getId()); }; }
@Bean public Guard<OrderState, OrderEvent> paymentGuard() { return context -> { Order order = context.getMessage().getHeaders().get("order", Order.class); BigDecimal paidAmount = context.getMessage().getHeaders().get("paidAmount", BigDecimal.class); return order.getTotalAmount().compareTo(paidAmount) == 0; }; } }
|
2. 用户认证流程
🔐 用户认证状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public enum UserAuthState { UNREGISTERED, REGISTERED, EMAIL_VERIFIED, PHONE_VERIFIED, ACTIVE, SUSPENDED, LOCKED, DELETED }
public enum UserAuthEvent { REGISTER, VERIFY_EMAIL, VERIFY_PHONE, ACTIVATE, LOGIN_SUCCESS, LOGIN_FAILED, PASSWORD_RESET, SUSPEND, LOCK, DELETE }
|
3. 审批工作流
📝 审批流程状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public enum ApprovalState { DRAFT, PENDING_REVIEW, UNDER_REVIEW, APPROVED, REJECTED, REVISION_NEEDED, CANCELLED }
public enum ApprovalEvent { SUBMIT, ASSIGN_REVIEWER, START_REVIEW, APPROVE, REJECT, REQUEST_REVISION, REVISE, CANCEL }
|
🎯 状态机最佳实践
1. 设计原则
🏗️ 单一职责原则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class PaidState implements OrderState { @Override public void handle(Order order, OrderEvent event) { switch (event) { case SHIP: shipOrder(order); break; case REFUND: processRefund(order); break; } } }
|
🔒 开闭原则
1 2 3 4 5 6 7 8 9 10 11 12
| public class ExpressShippingState implements OrderState { @Override public void handle(Order order, OrderEvent event) { }
@Override public OrderStateEnum getState() { return OrderStateEnum.EXPRESS_SHIPPING; } }
|
🤝 依赖倒置原则
1 2 3 4 5 6 7 8 9
| public interface StateMachine { void processEvent(StatefulEntity entity, Event event); }
public interface OrderState { void handle(Order order, OrderEvent event); OrderStateEnum getState(); }
|
2. 性能优化
🚀 状态机池化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Service public class StateMachinePool {
private final Map<String, StateMachine<OrderState, OrderEvent>> machinePool = new ConcurrentHashMap<>();
public StateMachine<OrderState, OrderEvent> getMachine(String machineId) { return machinePool.computeIfAbsent(machineId, this::createMachine); }
private StateMachine<OrderState, OrderEvent> createMachine(String machineId) { StateMachine<OrderState, OrderEvent> machine = stateMachineFactory.create(); machine.start(); return machine; }
@Scheduled(fixedRate = 300000) public void cleanupIdleMachines() { } }
|
📊 状态缓存优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Service public class StateCacheService {
@Autowired private RedisTemplate<String, Object> redisTemplate;
private static final String STATE_CACHE_PREFIX = "state:cache:";
public void cacheState(String entityId, OrderState state) { String key = STATE_CACHE_PREFIX + entityId; redisTemplate.opsForValue().set(key, state, Duration.ofHours(1)); }
public OrderState getCachedState(String entityId) { String key = STATE_CACHE_PREFIX + entityId; return (OrderState) redisTemplate.opsForValue().get(key); }
public void cacheStateHistory(String entityId, List<StateChange> history) { String key = STATE_CACHE_PREFIX + entityId + ":history"; redisTemplate.opsForValue().set(key, history, Duration.ofDays(30)); } }
|
3. 监控和调试
📈 状态机监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| @Service @Slf4j public class StateMachineMonitor {
private final MeterRegistry meterRegistry; private final Map<String, Counter> transitionCounters = new ConcurrentHashMap<>(); private final Map<String, Timer> transitionTimers = new ConcurrentHashMap<>();
public void recordTransition(String machineId, OrderState from, OrderState to, OrderEvent event) { String counterKey = String.format("state_machine.%s.transition.%s.%s.%s", machineId, from, to, event); transitionCounters.computeIfAbsent(counterKey, k -> Counter.builder(k).register(meterRegistry)) .increment(); }
public void recordTransitionTime(String machineId, OrderState from, OrderState to, OrderEvent event, long duration) { String timerKey = String.format("state_machine.%s.transition_time.%s.%s.%s", machineId, from, to, event); transitionTimers.computeIfAbsent(timerKey, k -> Timer.builder(k).register(meterRegistry)) .record(duration, TimeUnit.MILLISECONDS); }
public void recordStateDistribution(String machineId, OrderState state) { Gauge.builder("state_machine." + machineId + ".state_distribution", () -> 1) .tag("state", state.name()) .register(meterRegistry); } }
|
🔍 状态机调试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| @Service @Slf4j public class StateMachineDebugger {
@Autowired private StateMachineMonitor monitor;
public void debugTransition(Order order, OrderEvent event, OrderState from, OrderState to) { log.info("=== 状态机调试信息 ==="); log.info("订单ID: {}", order.getId()); log.info("事件: {}", event); log.info("状态转换: {} -> {}", from, to); log.info("订单信息: {}", order.toString()); log.info("时间戳: {}", LocalDateTime.now());
monitor.recordTransition("order", from, to, event);
validateStateTransition(from, to, event);
logStateHistory(order); }
private void validateStateTransition(OrderState from, OrderState to, OrderEvent event) { boolean isValid = switch (from) { case DRAFT -> event == OrderEvent.SUBMIT && to == OrderState.PENDING; case PENDING -> (event == OrderEvent.PAY && to == OrderState.PAID) || (event == OrderEvent.CANCEL && to == OrderState.CANCELLED); case PAID -> event == OrderEvent.SHIP && to == OrderState.SHIPPED; default -> false; };
if (!isValid) { log.warn("检测到异常状态转换: {} --[{}]--> {}", from, event, to); } }
private void logStateHistory(Order order) { List<OrderStateHistory> history = orderStateHistoryRepository .findByOrderIdOrderByCreatedAtDesc(order.getId());
log.info("状态变更历史:"); history.forEach(h -> log.info(" {}: {} -> {} (事件: {})", h.getCreatedAt(), h.getFromState(), h.getToState(), h.getEvent())); } }
|
📚 总结与建议
1. 状态机选择指南
🎯 简单业务场景
- 推荐:枚举实现
- 适用场景:状态较少,转换逻辑简单的业务
- 优点:实现简单,性能好,易于理解
- 示例:订单状态管理,用户状态管理
📈 中等复杂度业务
- 推荐:状态模式实现
- 适用场景:状态较多,转换逻辑相对复杂的业务
- 优点:代码结构清晰,易于扩展和维护
- 示例:审批工作流,任务状态管理
🏢 复杂企业级应用
- 推荐:Spring State Machine
- 适用场景:状态复杂,转换规则多,支持分布式部署
- 优点:功能强大,支持持久化,监控完善
- 示例:大型电商平台,企业级工作流系统
2. 实施建议
📋 实施步骤
- 需求分析:明确业务状态和转换规则
- 状态建模:绘制状态图,定义状态和事件
- 选择实现方式:根据复杂度选择合适的状态机实现
- 代码实现:实现状态类和转换逻辑
- 测试验证:编写单元测试和集成测试
- 监控部署:配置监控和告警
- 优化调优:根据实际运行情况进行优化
⚠️ 注意事项
- 状态一致性:确保状态变更的原子性
- 异常处理:完善的异常处理和回滚机制
- 性能监控:实时监控状态机性能指标
- 文档维护:及时更新状态机文档
- 版本兼容:考虑状态机升级的兼容性
🔧 常见问题解决
- 状态机死锁:合理设计状态转换,避免循环依赖
- 性能问题:使用状态机池化,合理使用缓存
- 调试困难:添加详细日志,完善监控指标
- 扩展性问题:预留扩展接口,遵循开闭原则
3. 发展趋势
🌟 智能化状态机
- AI驱动:使用AI预测状态转换
- 自适应:根据历史数据自动调整转换规则
- 自动化:自动发现和修复状态不一致问题
🔗 微服务状态机
- 分布式协调:跨服务状态一致性保证
- 事件驱动:基于事件的状态机协作
- Saga模式:分布式事务的状态机实现
📊 云原生状态机
- Kubernetes集成:使用Kubernetes原生状态管理
- 服务网格:基于Istio的状态机编排
- 无服务器:Serverless环境下的状态机
🔗 参考资料
📖 推荐书籍
🛠️ 工具框架
📊 在线资源
🚀 Java状态机,从简单枚举到企业级Spring State Machine的完整实现指南!
🎯 掌握状态机设计,让复杂业务流程变得清晰可控!