状态机spring-statemachine使用

状态机spring-statemachine使用

起男 20 2025-05-07

状态机spring-statemachine使用

导入依赖

        <dependency>
            <groupId>org.springframework.statemachine</groupId>
            <artifactId>spring-statemachine-starter</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

定义状态

@RequiredArgsConstructor
@Getter
public enum OrderStatus {

    WAIT_PAYMENT(1, "待支付"),
    WAIT_DELIVER(2, "待发货"),
    WAIT_RECEIVE(3, "待收货"),
    FINISH(4, "已完成");

    private final Integer key;
    private final String desc;

    public static OrderStatus getByKey(Integer key){
        for (OrderStatus os : values()) {
            if (os.key.equals(key)) {
                return os;
            }
        }
        return null;
    }
}

定义事件

public enum OrderStatusChangeEvent {
    // 支付,发货,确认收货
    PAYED, DELIVERY, RECEIVED;
}

配置对应关系

@Component
@EnableStateMachine(name = "orderStateMachine")
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStatus, OrderStatusChangeEvent> {

    //配置状态
    public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception {
        states
                .withStates()
                .initial(OrderStatus.WAIT_PAYMENT)//初始化状态
                .states(EnumSet.allOf(OrderStatus.class));//状态枚举
    }

    //配置状态转换关系
    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);
    }
}

监听器

@Component
@WithStateMachine(name = "orderStateMachine")
@Slf4j
public class EventListener {

    @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
    public void payTransition(Message<OrderStatusChangeEvent> message) {
        log.info("支付");
    }
    @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
    public void deliverTransition(Message<OrderStatusChangeEvent> message) {
        log.info("发货");
    }
    @OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
    public void receiveTransition(Message<OrderStatusChangeEvent> message) {
        log.info("确认收货");
    }
}

测试

@SpringBootTest
public class StatusTests {

    @Autowired
    private StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine;

    @Test
    void test01(){
        Order order = new Order();
        order.setStatus(OrderStatus.WAIT_PAYMENT.getKey());
        //启动状态机
        orderStateMachine.start();

        Message<OrderStatusChangeEvent> message1 = MessageBuilder.withPayload(OrderStatusChangeEvent.PAYED)
                .setHeader("order", order).build();
        orderStateMachine.sendEvent(message1);
        
        Message<OrderStatusChangeEvent> message2 = MessageBuilder.withPayload(OrderStatusChangeEvent.DELIVERY)
                .setHeader("order", order).build();
        orderStateMachine.sendEvent(message2);
        
        Message<OrderStatusChangeEvent> message3 = MessageBuilder.withPayload(OrderStatusChangeEvent.RECEIVED)
                .setHeader("order", order).build();
        orderStateMachine.sendEvent(message3);
    }
}