前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot集成Spring Statemachine(状态机)示例

SpringBoot集成Spring Statemachine(状态机)示例

原创
作者头像
程序员波特
发布2024-04-05 21:03:07
2320
发布2024-04-05 21:03:07
举报
文章被收录于专栏:魔法书魔法书

前言

本文将以电商项目中的订单状态转换这个典型的场景。从订单的创建到支付、发货、完成等状态来使用状态机进行管理。如果使用传统的if-else或者switch语句来管理这些状态,代码会变得非常臃肿且难以维护。而状态机提供了一种更加结构化和可维护的方式来管理这些状态转换。

SpringBoot如何集成状态机?

SpringBoot提供了对状态机的良好支持,我们可以通过添加相关依赖和配置来轻松集成状态机。在项目中,我选择了Spring Statemachine作为状态机框架,它提供了丰富的功能和灵活的扩展性。

下面我们就来编写Spring Boot集成Spring Statemachine的简单示例代码吧。

  1. 首先,我们需要添加Spring Statemachine的依赖到Spring Boot项目的pom.xml文件中:
代码语言:java
复制
<dependencies>  
    <!-- 其他依赖 -->  
  
    <!-- Spring Statemachine -->  
    <dependency>  
        <groupId>org.springframework.statemachine</groupId>  
        <artifactId>spring-statemachine-core</artifactId>  
        <version>2.3.1</version>  
    </dependency>  
</dependencies>
  1. 然后,我们定义订单的状态和事件:
代码语言:java
复制
// 定义订单状态  
public enum OrderState {  
    CREATED,  
    PAID,  
    SHIPPED,  
    COMPLETED  
}  
  
// 定义订单事件  
public enum OrderEvent {  
    PAY,  
    SHIP,  
    COMPLETE  
}
  1. 接下来,我们配置状态机:
代码语言:java
复制
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.statemachine.config.EnableStateMachine;  
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;  
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;  
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;  
import org.springframework.statemachine.state.State;  
import org.springframework.statemachine.transition.Transition;  
  
import java.util.EnumSet;  
  
@Configuration // 标识这个类是一个Spring配置类  
@EnableStateMachine // 启用Spring State Machine的功能  
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter {  
  
    // 配置状态机状态  
    @Override  
    public void configure(StateMachineStateConfigurer<OrderState, String> states) throws Exception {  
        states  
                // 定义CREATED状态  
                .withStates()  
                .initial(OrderState.CREATED) // 设置CREATED为初始状态  
                .state(OrderState.CREATED, createStateBuilder(OrderState.CREATED))  
                .state(OrderState.PAID, createStateBuilder(OrderState.PAID))  
                .state(OrderState.SHIPPED, createStateBuilder(OrderState.SHIPPED))  
                .state(OrderState.COMPLETED, createStateBuilder(OrderState.COMPLETED));  
    }  
  
    // 创建状态构建器,可以添加更多配置(如子状态、进入/退出动作等)  
    private State<OrderState, String> createStateBuilder(OrderState state) {  
        return new StateMachineStateBuilder<OrderState, String>(state)  
                .build();  
    }  
  
    // 配置状态机转换  
    @Override  
    public void configure(StateMachineTransitionConfigurer<OrderState, String> transitions) throws Exception {  
        transitions  
                .withExternal()  
                .source(OrderState.CREATED).target(OrderState.PAID).event("PAY")  
                .and()  
                .source(OrderState.PAID).target(OrderState.SHIPPED).event("SHIP")  
                .and()  
                .source(OrderState.SHIPPED).target(OrderState.COMPLETED).event("COMPLETE");  
    }  
  
    // 创建状态机的Bean  
    @Bean(name = "orderStateMachine")  
    public StateMachine<OrderState, String> orderStateMachine(StateMachineFactory<OrderState, String> factory) throws Exception {  
        return factory.getStateMachine("orderStateMachine");  
    }  
  
    // 可以添加更多配置方法,例如监听器配置、守卫配置等  
  
}
  1. 现在,我们可以创建一个服务来操作状态机:
代码语言:java
复制
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.statemachine.state.State;  
import org.springframework.statemachine.StateMachine;  
import org.springframework.stereotype.Service;  
  
@Service  
public class OrderService {  
  
    private final StateMachine<OrderState, OrderEvent> orderStateMachine;  
  
    @Autowired  
    public OrderService(StateMachine<OrderState, OrderEvent> orderStateMachine) {  
        this.orderStateMachine = orderStateMachine;  
    }  
  
    public void createOrder() {  
        // 假设订单已经创建,现在触发状态机到CREATED状态  
        // 实际上,这里可能涉及订单的创建逻辑  
        orderStateMachine.start();  
        System.out.println("Order created and state machine started in state: " + orderStateMachine.getState().getId());  
    }  
  
    public void payOrder() {  
        // 发送支付事件,状态机将转移到PAID状态  
        orderStateMachine.sendEvent(OrderEvent.PAY);  
        System.out.println("Order paid and state machine is now in state: " + orderStateMachine.getState().getId());  
    }  
  
    public void shipOrder() {  
        // 发送发货事件,状态机将转移到SHIPPED状态  
        orderStateMachine.sendEvent(OrderEvent.SHIP);  
        System.out.println("Order shipped and state machine is now in state: " + orderStateMachine.getState().getId());  
    }  
  
    public void completeOrder() {  
        // 发送完成事件,状态机将转移到COMPLETED状态  
        orderStateMachine.sendEvent(OrderEvent.COMPLETE);  
        System.out.println("Order completed and state machine is now in state: " + orderStateMachine.getState().getId());  
    }  
  
    public State<OrderState> getCurrentState() {
        return orderStateMachine.getState();
    }
}

类说明

OrderStateMachineConfig类是一个Spring配置类,它扩展了StateMachineConfigurerAdapter来配置订单的状态机。它使用了Spring State Machine的注解@EnableStateMachine来启用状态机的功能。

方法详解:

  1. configure(StateMachineStateConfigurer<OrderState, String> states):这个方法用于配置状态机的状态。它使用withStates方法定义了订单的所有可能状态,并设置了CREATED为初始状态。
  2. createStateBuilder(OrderState state):这是一个私有辅助方法,它创建一个状态构建器,并返回配置好的状态对象。你可以在这个方法里添加更多状态的配置,比如子状态、进入/退出动作等。
  3. configure(StateMachineTransitionConfigurer<OrderState, String> transitions):这个方法用于配置状态机之间的转换(即触发事件后从一个状态转移到另一个状态)。它定义了从CREATED到PAID、从PAID到SHIPPED以及从SHIPPED到COMPLETED的转换事件。
  4. orderStateMachine(StateMachineFactory<OrderState, String> factory):这个方法是一个Bean方法,它创建了状态机的实例并将其注册到Spring容器中。通过StateMachineFactory,我们创建了一个名为"orderStateMachine"的状态机实例。

现在,我们已经配置了状态机并创建了服务来操作它。接下来,你可以在应用的任何部分注入OrderService,并调用相应的方法来改变订单的状态。

例如,在一个控制器中,你可以这样做:

代码语言:java
复制
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  
  
@RestController  
public class OrderController {  
  
    private final OrderService orderService;  
  
    @Autowired  
    public OrderController(OrderService orderService) {  
        this.orderService = orderService;  
    }  
  
    @GetMapping("/create-order")  
    public String createOrder() {  
        orderService.createOrder();  
        return "Order created";  
    }  
  
    @GetMapping("/pay-order")  
    public String payOrder() {  
        orderService.payOrder();  
        return "Order paid";  
    }  
  
    @GetMapping("/ship-order")  
    public String shipOrder() {  
        orderService.shipOrder();  
        return "Order shipped";  
    }  
  
    @GetMapping("/complete-order")  
    public String completeOrder() {  
        orderService.completeOrder();  
        return "Order completed";  
    }  
  
    @GetMapping("/order-status")  
    public String getOrderStatus() {  
        State<OrderState> currentState = orderService.getCurrentState();  
        return "Current order status: " + currentState.getId();  
    } 

在上面的示例代码中,我们定义了一个OrderController,它提供了几个HTTP端点来模拟订单状态的改变和查询当前状态。你可以通过访问这些端点来与状态机交互。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • SpringBoot如何集成状态机?
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com