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. 易于维护和测试:各组件之间通过接口通信,便于单元测试和替换实现

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

相关推荐
Aurora_NeAr6 分钟前
大数据之路:阿里巴巴大数据实践——大数据领域建模综述
大数据·后端
Olrookie8 分钟前
若依前后端分离版学习笔记(一)——本地部署
笔记·后端·开源
魏振东11 分钟前
COLA
后端
凉冰不加冰14 分钟前
Spring Boot自动配置原理深度解析
java·spring boot·后端
非优秀程序员20 分钟前
8 个提升开发者效率的小众 AI 项目
前端·人工智能·后端
rzl0239 分钟前
SpringBoot总结
spring boot·后端·firefox
小鱼人爱编程2 小时前
Java基石--反射让你直捣黄龙
前端·spring boot·后端
hqxstudying2 小时前
J2EE模式---服务层模式
java·数据库·后端·spring·oracle·java-ee
GM_8282 小时前
【最新最完整】SpringAI-1.0.0开发MCP Server,搭建MCP Client 实战笔记(进阶+详细+完整代码)
java·后端·ai编程·springai·mcp
程序员爱钓鱼2 小时前
Go语言实战案例-滑动窗口最大值
后端·google·go