Here’s an example of an order flow:

@Data
public class Order {
    private int id;
    private OrderStatus status;
    @Override
    public String toString() {
        return Order No. : + id + ", order status:+ status; }} /** * OrderStatus */ public enum OrderStatus {// OrderStatus; } /** * OrderStatusChangeEvent */ public enum OrderStatusChangeEvent { } public interface IOrderService {// create new Order Order create(); Order pay(int id); // Order deliver(int id); Order receive(int id); Map<Integer, Order> getOrders(); } @Service("orderService")
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine;
 
    @Autowired
    private StateMachinePersister<OrderStatus, OrderStatusChangeEvent, Order> persister;
 
    private int id = 1;
    private Map<Integer, Order> orders = new HashMap<>();

    public Order create() {
        Order order = new Order();
        order.setStatus(OrderStatus.WAIT_PAYMENT);
        order.setId(id++);
        orders.put(order.getId(), order);
        return order;
    }

    public Order pay(int id) {
        Order order = orders.get(id);
        System.out.println("Thread name:" + Thread.currentThread().getName() + "Attempt payment, Order No. :" + id);
        Message message = MessageBuilder.withPayload(OrderStatusChangeEvent.PAYED).setHeader("order", order).build();
        if(! sendEvent(message, order)) { System.out.println("Thread name:" + Thread.currentThread().getName() + "Payment failed, status abnormal, order No. :" + id);
        }
        return orders.get(id);
    }

    public Order deliver(int id) {
        Order order = orders.get(id);
        System.out.println("Thread name:" + Thread.currentThread().getName() + "Attempted shipment, Order No. :" + id);
        if(! sendEvent(MessageBuilder.withPayload(OrderStatusChangeEvent.DELIVERY).setHeader("order", order).build(), orders.get(id))) {
            System.out.println("Thread name:" + Thread.currentThread().getName() + "Delivery failure, abnormal status, order No. :" + id);
        }
        return orders.get(id);
    }

    public Order receive(int id) {
        Order order = orders.get(id);
        System.out.println("Thread name:" + Thread.currentThread().getName() + "Try to receive goods, order no. :" + id);
        if(! sendEvent(MessageBuilder.withPayload(OrderStatusChangeEvent.RECEIVED).setHeader("order", order).build(), orders.get(id))) {
            System.out.println("Thread name:" + Thread.currentThread().getName() + "Failed to receive, abnormal status, order No. :" + id);
        }
        return orders.get(id);
    }
 

    public Map<Integer, Order> getOrders() {
        returnorders; } /** * send the order status transition event ** @param message * @param order * @return
     */
    private synchronized boolean sendEvent(Message<OrderStatusChangeEvent> message, Order order) {
        boolean result = false; try { orderStateMachine.start(); // Try to restore the state machine state persister.restore(orderStateMachine, order); // Add delay for Thread safety test thread.sleep (1000); result = orderStateMachine.sendEvent(message); // Persist state machine state persister.persist(orderStateMachine, order); } catch (Exception e) { e.printStackTrace(); } finally { orderStateMachine.stop(); }returnresult; } } package com.gupaoedu.vip.pattern.state.order; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.statemachine.StateMachineContext; import org.springframework.statemachine.StateMachinePersist; import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.StateMachineConfigurerAdapter; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; import org.springframework.statemachine.persist.DefaultStateMachinePersister; import org.springframework.statemachine.support.DefaultStateMachineContext; import java.util.EnumSet; /** * Order state machine Configuration */ @configuration@enableStatemachine (name ="orderStateMachine") public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStatus, OrderStatusChangeEvent> {/** * configuration status * @param States * @throws Exception */ public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception { states .withStates() .initial(OrderStatus.WAIT_PAYMENT) .states(EnumSet.allOf(OrderStatus.class)); } /** * Configure the state transition event relationship * @param Transitions * @throws Exception */ public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderStatusChangeEvent> transitions) throws Exception { transitions .withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED) .and() .withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERY)  .and() .withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED); } /** * Persistent configuration * in actual use, you can cooperate with redis, etc., for persistent operation * @return
     */
    @Bean
    public DefaultStateMachinePersister persister() {returnnew DefaultStateMachinePersister<>(new StateMachinePersist<Object, Object, Order>() { @Override public void write(StateMachineContext<Object, Object> context, Override public StateMachineContext<Object, Object>read(Order Order) throws Exception {// The state in Order is directly obtained without a persistent read operationreturnnew DefaultStateMachineContext(order.getStatus(), null, null, null); }}); } } import org.springframework.messaging.Message; import org.springframework.statemachine.annotation.OnTransition; import org.springframework.statemachine.annotation.WithStateMachine; import org.springframework.stereotype.Component; @Component("orderStateListener")
@WithStateMachine(name = "orderStateMachine")
public class OrderStateListenerImpl{
 
    @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
    public boolean payTransition(Message<OrderStatusChangeEvent> message) {
        Order order = (Order) message.getHeaders().get("order");
        order.setStatus(OrderStatus.WAIT_DELIVER);
        System.out.println("Payment, state machine feedback:" + message.getHeaders().toString());
        return true;
    }
 
    @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
    public boolean deliverTransition(Message<OrderStatusChangeEvent> message) {
        Order order = (Order) message.getHeaders().get("order");
        order.setStatus(OrderStatus.WAIT_RECEIVE);
        System.out.println("Delivery, state machine feedback:" + message.getHeaders().toString());
        return true;
    }
 
    @OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
    public boolean receiveTransition(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get("order");
        order.setStatus(OrderStatus.FINISH);
        System.out.println("Received goods, state machine feedback information:" + message.getHeaders().toString());
        return true;
    }
}

@SpringBootApplication
public class Test {
    public static void main(String[] args) {

        Thread.currentThread().setName("Main thread");

        ConfigurableApplicationContext context = SpringApplication.run(Test.class,args);

        IOrderService orderService = (IOrderService)context.getBean("orderService");

        orderService.create();
        orderService.create();

        orderService.pay(1);

        new Thread("Client thread"){
            @Override
            public void run() {
                orderService.deliver(1);
                orderService.receive(1);
            }
        }.start();

        orderService.pay(2);
        orderService.deliver(2);
        orderService.receive(2);

        System.out.println("Status of all orders:"+ orderService.getOrders()); }}Copy the code