spring 状态机demo
<dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-core</artifactId> <version>2.0.1.RELEASE</version> </dependency>
// 作为数据源 public class Data { public static List<Order> orderList = new ArrayList<>(); public static void create(Order order) { orderList.add(order); } public static Order getById(String id) { return orderList.stream().filter(item -> Objects.equals(id, item.getId())).findFirst().orElse(null); } public static void update(Order order) { orderList.stream().filter(item -> Objects.equals(order.getId(), item.getId())).findFirst().ifPresent( item -> item.setStatus(order.getStatus())); } }
// 订单实体 public class Order { private String id; private OrderStatus status; }
/** * @author yangxj * @date 2023/10/16 10:37 * 状态机配置 */ @Configuration @EnableStateMachine(name = "orderStatemachine") public class OrderStatemachineConfig extends StateMachineConfigurerAdapter<OrderStatus,OrderStatusChangeEvent> { @Bean(name = "stateMachinePersister") public StateMachinePersister<OrderStatus, OrderStatusChangeEvent, String> getPersister() { return new DefaultStateMachinePersister<>(new StateMachinePersist<OrderStatus, OrderStatusChangeEvent, String>() { @Override public void write(StateMachineContext<OrderStatus, OrderStatusChangeEvent> context, String contextObj) throws Exception { map.put(contextObj, context); } @Override public StateMachineContext<OrderStatus, OrderStatusChangeEvent> read(String contextObj) throws Exception { return map.get(contextObj); } Map<String, StateMachineContext<OrderStatus, OrderStatusChangeEvent>> map = new HashMap<>(); }); } /** * 配置状态 */ @Override public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception { states.withStates() .initial(OrderStatus.WAIT_PAYMENT) .states(EnumSet.allOf(OrderStatus.class)); } /** * 配置转换事件 */ @Override public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderStatusChangeEvent> transitions) throws Exception { transitions //支付事件:待支付-》待发货 .withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED_EVENT) .and() //发货事件:待发货-》待收货 .withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERED_EVENT) .and() //收货事件:待收货-》已完成 .withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED_EVENT); } }
// 订单状态枚举 public enum OrderStatus { WAIT_PAYMENT(1, "待支付"), WAIT_DELIVER(2, "待发货"), WAIT_RECEIVE(3, "待收货"), FINISH(4, "已完成"); private final Integer key; private final String name; OrderStatus(Integer key, String name) { this.key = key; this.name = name; } public Integer getKey() { return key; } public String getName() { return name; } }
// 订单状态改变事件
public enum OrderStatusChangeEvent {
// 支付,发货,确认收货
PAYED_EVENT,
DELIVERED_EVENT,
RECEIVED_EVENT;
}
// 事件监听处理 @WithStateMachine(name = "orderStatemachine") @Slf4j public class OrderStatusChangeEventListener { @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER") public boolean payTransition(Message<OrderStatusChangeEvent> message) { Order order = (Order) message.getHeaders().get("order"); log.info("支付,状态机反馈信息:{}", message.getHeaders()); //更新订单 order.setStatus(OrderStatus.WAIT_DELIVER); Data.update(order); return true; } @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE") public boolean deliverTransition(Message<OrderStatusChangeEvent> message) { Order order = (Order) message.getHeaders().get("order"); log.info("发货,状态机反馈信息:{}", message.getHeaders()); //更新订单 order.setStatus(OrderStatus.WAIT_RECEIVE); Data.update(order); return true; } @OnTransition(source = "WAIT_RECEIVE", target = "FINISH") public boolean receiveTransition(Message<OrderStatusChangeEvent> message) { Order order = (Order) message.getHeaders().get("order"); log.info("确认收货,状态机反馈信息:{}", message.getHeaders()); //更新订单 order.setStatus(OrderStatus.FINISH); Data.update(order); return true; } }
@RestController @RequestMapping("/order") public class OrderController { @Resource private OrderService orderService; /** * 根据id查询订单 * * @return */ @RequestMapping("/getById") public Order getById(@RequestParam("id") String id) { //根据id查询订单 Order order = orderService.getById(id); return order; } /** * 创建订单 * * @return */ @RequestMapping("/create") public String create(@RequestBody Order order) { //创建订单 orderService.create(order); return "sucess"; } /** * 对订单进行支付 * * @param id * @return */ @RequestMapping("/pay") public String pay(@RequestParam("id") String id) { //对订单进行支付 orderService.pay(id); return "success"; } /** * 对订单进行发货 * * @param id * @return */ @RequestMapping("/deliver") public String deliver(@RequestParam("id") String id) { //对订单进行确认收货 orderService.deliver(id); return "success"; } /** * 对订单进行确认收货 * * @param id * @return */ @RequestMapping("/receive") public String receive(@RequestParam("id") String id) { //对订单进行确认收货 orderService.receive(id); return "success"; } } /** * @author yangxj * @date 2023/10/16 10:55 */ @Slf4j @Service public class OrderService { @Resource StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine; @Resource StateMachinePersister<OrderStatus, OrderStatusChangeEvent, String> stateMachinePersister; /** * 创建订单 * * @param order * @return */ public Order create(Order order) { order.setStatus(OrderStatus.WAIT_PAYMENT); Data.create(order); return order; } /** * 对订单进行支付 * * @param id * @return */ public Order pay(String id) { log.info("线程名称:{},尝试支付,订单号:{}", Thread.currentThread().getName(), id); Order order = Data.getById(id); if (!sendEvent(OrderStatusChangeEvent.PAYED_EVENT, order)) { log.error("线程名称:{},支付失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order); throw new RuntimeException("支付失败, 订单状态异常"); } return order; } /** * 对订单进行发货 * * @param id * @return */ public Order deliver(String id) { Order order = Data.getById(id); log.info("线程名称:{},尝试发货,订单号:{}", Thread.currentThread().getName(), id); if (!sendEvent(OrderStatusChangeEvent.DELIVERED_EVENT, order)) { log.error("线程名称:{},发货失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order); throw new RuntimeException("发货失败, 订单状态异常"); } return order; } /** * 对订单进行确认收货 * * @param id * @return */ public Order receive(String id) { Order order = Data.getById(id); log.info("线程名称:{},尝试收货,订单号:{}", Thread.currentThread().getName(), id); if (!sendEvent(OrderStatusChangeEvent.RECEIVED_EVENT, order)) { log.error("线程名称:{},收货失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order); throw new RuntimeException("收货失败, 订单状态异常"); } return order; } /** * 发送订单状态转换事件 * synchronized修饰保证这个方法是线程安全的 * * @param changeEvent * @param order * @return */ private synchronized boolean sendEvent(OrderStatusChangeEvent changeEvent, Order order) { boolean result = false; try { // 状态机重置 stateMachinePersister.restore(orderStateMachine, order.getId()); Message<OrderStatusChangeEvent> message = MessageBuilder.withPayload(changeEvent).setHeader("order", order).build(); result = orderStateMachine.sendEvent(message); // 状态机持久化 stateMachinePersister.persist(orderStateMachine, order.getId()); } catch (Exception e) { log.error("订单操作失败, order: {}", order, e); } finally { orderStateMachine.stop(); } return result; } public Order getById(String id) { return Data.getById(id); } }