Spring高级开发:状态机/事件/插件

Spring 状态机与事件机制插件开发示例

我将为您演示一个完整的 Spring 状态机实现,包含状态机配置、事件机制和可扩展的插件体系。以下是一个订单处理系统的示例:

1. 添加依赖(pom.xml)

xml 复制代码
<dependencies>
    <!-- Spring State Machine -->
    <dependency>
        <groupId>org.springframework.statemachine</groupId>
        <artifactId>spring-statemachine-starter</artifactId>
        <version>4.2.0</version>
    </dependency>
    
    <!-- Spring Event 相关 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>6.0.9</version>
    </dependency>
</dependencies>

2. 定义核心接口和类

2.1 状态和事件枚举

java 复制代码
// 状态枚举
public enum OrderState {
    NEW, 
    PAYMENT_PENDING, 
    PAID, 
    SHIPPED, 
    DELIVERED, 
    CANCELLED
}

// 事件枚举
public enum OrderEvent {
    CREATE_ORDER, 
    INITIATE_PAYMENT, 
    PAYMENT_COMPLETED, 
    SHIP_ORDER, 
    DELIVERY_CONFIRMED, 
    CANCEL_ORDER
}

2.2 插件接口定义

java 复制代码
// 状态变更监听器接口
public interface StateChangeListener {
    void onStateChange(OrderState from, OrderState to, String orderId);
}

// 订单操作插件接口
public interface OrderOperationPlugin {
    void execute(String orderId, OrderState currentState);
}

// 插件管理器接口
public interface PluginManager {
    void registerStateChangeListener(StateChangeListener listener);
    void notifyStateChange(OrderState from, OrderState to, String orderId);
    void executePlugins(String orderId, OrderState currentState);
}

3. 实现状态机配置

java 复制代码
@Configuration
@EnableStateMachine
public class OrderStateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {

    @Autowired
    private List<OrderOperationPlugin> plugins;

    @Override
    public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
        states
            .withStates()
            .initial(OrderState.NEW)
            .state(OrderState.PAYMENT_PENDING)
            .junction(OrderState.PAID)
            .end(OrderState.DELIVERED)
            .end(OrderState.CANCELLED)
            .fork(OrderState.SHIPPED);
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
        transitions
            .withExternal()
                .source(OrderState.NEW).target(OrderState.PAYMENT_PENDING)
                .event(OrderEvent.CREATE_ORDER)
                
            .and().withExternal()
                .source(OrderState.PAYMENT_PENDING).target(OrderState.PAID)
                .event(OrderEvent.INITIATE_PAYMENT)
                
            .and().withExternal()
                .source(OrderState.PAID).target(OrderState.SHIPPED)
                .event(OrderEvent.SHIP_ORDER)
                
            .and().withExternal()
                .source(OrderState.SHIPPED).target(OrderState.DELIVERED)
                .event(OrderEvent.DELIVERY_CONFIRMED)
                
            .and().withExternal()
                .source(OrderState.NEW).target(OrderState.CANCELLED)
                .event(OrderEvent.CANCEL_ORDER)
                
            .and().withExternal()
                .source(OrderState.PAYMENT_PENDING).target(OrderState.CANCELLED)
                .event(OrderEvent.CANCEL_ORDER);
    }
    
    @Bean
    public PluginManager pluginManager() {
        return new DefaultPluginManager(plugins);
    }
}

4. 插件实现

4.1 默认插件管理器

java 复制代码
@Component
public class DefaultPluginManager implements PluginManager {
    private final List<StateChangeListener> stateChangeListeners = new ArrayList<>();
    private final List<OrderOperationPlugin> operationPlugins;

    public DefaultPluginManager(List<OrderOperationPlugin> plugins) {
        this.operationPlugins = plugins;
    }

    @Override
    public void registerStateChangeListener(StateChangeListener listener) {
        stateChangeListeners.add(listener);
    }

    @Override
    public void notifyStateChange(OrderState from, OrderState to, String orderId) {
        stateChangeListeners.forEach(listener -> listener.onStateChange(from, to, orderId));
    }

    @Override
    public void executePlugins(String orderId, OrderState currentState) {
        operationPlugins.forEach(plugin -> plugin.execute(orderId, currentState));
    }
}

4.2 示例插件实现

java 复制代码
// 日志记录插件
@Component
public class LoggingPlugin implements OrderOperationPlugin {
    @Override
    public void execute(String orderId, OrderState currentState) {
        System.out.println("订单 " + orderId + " 当前状态: " + currentState + " - 正在记录日志");
    }
}

// 邮件通知插件
@Component
public class EmailNotificationPlugin implements OrderOperationPlugin {
    @Override
    public void execute(String orderId, OrderState currentState) {
        System.out.println("订单 " + orderId + " 当前状态: " + currentState + " - 发送邮件通知");
    }
}

// 库存管理插件
@Component
public class InventoryUpdatePlugin implements OrderOperationPlugin {
    @Override
    public void execute(String orderId, OrderState currentState) {
        if (currentState == OrderState.PAID) {
            System.out.println("订单 " + orderId + " 已支付,正在更新库存");
        }
    }
}

5. 状态监听器实现

java 复制代码
@Component
public class AuditStateChangeListener implements StateChangeListener {
    @Override
    public void onStateChange(OrderState from, OrderState to, String orderId) {
        System.out.println("订单状态变更: " + orderId + " 从 " + from + " 到 " + to + " - 审计记录已创建");
    }
}

6. 服务层实现

java 复制代码
@Service
public class OrderService {

    @Autowired
    private StateMachine<OrderState, OrderEvent> stateMachine;

    @Autowired
    private PluginManager pluginManager;

    public OrderService() {
        // 注册监听器
        pluginManager.registerStateChangeListener(new AuditStateChangeListener());
    }

    public void handleOrderEvent(String orderId, OrderEvent event) {
        try {
            stateMachine.start();
            OrderState currentState = stateMachine.getState().getId();
            
            // 发送事件
            stateMachine.sendEvent(event);
            
            OrderState newState = stateMachine.getState().getId();
            
            // 触发状态变更监听器
            if (currentState != newState) {
                pluginManager.notifyStateChange(currentState, newState, orderId);
            }
            
            // 执行操作插件
            pluginManager.executePlugins(orderId, newState);
            
        } catch (Exception e) {
            System.err.println("处理订单事件失败: " + e.getMessage());
        } finally {
            stateMachine.stop();
        }
    }
}

7. 控制器示例

java 复制代码
@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/{orderId}/events")
    public ResponseEntity<String> sendEvent(@PathVariable String orderId, @RequestParam String event) {
        try {
            OrderEvent orderEvent = OrderEvent.valueOf(event.toUpperCase());
            orderService.handleOrderEvent(orderId, orderEvent);
            return ResponseEntity.ok("事件已处理: " + event);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body("无效的事件类型: " + event);
        }
    }
    
    @GetMapping("/{orderId}/status")
    public ResponseEntity<String> checkStatus(@PathVariable String orderId) {
        // 这里应该从存储中获取当前状态,为简化示例返回固定值
        return ResponseEntity.ok("订单 " + orderId + " 当前状态: 示例状态");
    }
}

8. 可扩展性说明

如何添加新插件:

java 复制代码
@Component
public class NewFeaturePlugin implements OrderOperationPlugin {
    @Override
    public void execute(String orderId, OrderState currentState) {
        // 新功能逻辑
    }
}

如何添加新状态监听器:

java 复制代码
@Component
public class NewStateChangeListener implements StateChangeListener {
    @Override
    public void onStateChange(OrderState from, OrderState to, String orderId) {
        // 新监听器逻辑
    }
}

使用示例:

shell 复制代码
# 创建订单
POST /orders/123/events?event=CREATE_ORDER

# 发起支付
POST /orders/123/events?event=INITIATE_PAYMENT

# 发货
POST /orders/123/events?event=SHIP_ORDER

# 确认送达
POST /orders/123/events?event=DELIVERY_CONFIRMED

# 取消订单
POST /orders/123/events?event=CANCEL_ORDER

这个实现具有以下特点:

  1. 灵活的状态机配置:使用 Spring StateMachine 配置订单状态流转
  2. 可扩展的插件系统:通过接口设计支持轻松添加新插件
  3. 事件驱动架构:利用状态变更事件触发相关业务逻辑
  4. 良好的分离关注点:核心状态机逻辑与业务插件解耦
  5. 易于维护和测试:各组件之间通过接口通信,便于单元测试和替换实现

您可以根据具体业务需求扩展更多状态、事件和插件功能。

相关推荐
uzong18 分钟前
技术故障复盘模版
后端
GetcharZp1 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程1 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研1 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack3 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9654 小时前
pip install 已经不再安全
后端
寻月隐君4 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github