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

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

相关推荐
六毛的毛24 分钟前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack31 分钟前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
315356691334 分钟前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong1 小时前
curl案例讲解
后端
一只叫煤球的猫2 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
大鸡腿同学3 小时前
身弱武修法:玄之又玄,奇妙之门
后端
轻语呢喃4 小时前
JavaScript :字符串模板——优雅编程的基石
前端·javascript·后端
MikeWe4 小时前
Paddle张量操作全解析:从基础创建到高级应用
后端
岫珩5 小时前
Ubuntu系统关闭防火墙的正确方式
后端
心之语歌5 小时前
Java高效压缩技巧:ZipOutputStream详解
java·后端