Spring Event实例

1. 定义事件类

// 设备故障事件(携带设备ID、故障描述、故障级别)
public class EquipmentFailureEvent extends ApplicationEvent {
    private String equipmentId;
    private String failureDescription;
    private FailureLevel level; // 枚举:CRITICAL, WARNING

    public EquipmentFailureEvent(Object source, String equipmentId, 
                                 String failureDescription, FailureLevel level) {
        super(source);
        this.equipmentId = equipmentId;
        this.failureDescription = failureDescription;
        this.level = level;
    }
    // getters...
}

// 故障级别枚举
public enum FailureLevel {
    CRITICAL, WARNING
}

2. 发布事件(设备服务) 

@Service
public class EquipmentService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    // 模拟设备故障上报
    @Transactional
    public void reportFailure(String equipmentId, String description, FailureLevel level) {
        // 1. 更新设备状态为 "故障"(数据库操作)
        updateEquipmentStatus(equipmentId, "FAULT");

        // 2. 发布故障事件(携带故障信息)
        eventPublisher.publishEvent(
            new EquipmentFailureEvent(this, equipmentId, description, level)
        );
    }
}

 3. 监听事件(多个监听器)

        3.1 实时告警(异步处理)

@Service
public class AlertService {
    // 异步监听所有设备故障事件
    @Async
    @EventListener
    public void handleEquipmentFailure(EquipmentFailureEvent event) {
        // 发送短信/邮件给运维人员
        sendAlert("设备ID: " + event.getEquipmentId() 
                + " 发生故障!详情: " + event.getFailureDescription());
    }

    private void sendAlert(String message) {
        System.out.println("[异步告警] " + message);
    }
}

 3.2 生成维修工单(条件监听)

@Service
public class MaintenanceService {
    // 仅当故障级别为 CRITICAL 时触发
    @EventListener(condition = "#event.level.name() == 'CRITICAL'")
    public void createMaintenanceOrder(EquipmentFailureEvent event) {
        String orderId = generateOrderId();
        System.out.println("[生成工单] 设备ID: " + event.getEquipmentId() 
                         + ", 工单号: " + orderId);
    }

    private String generateOrderId() {
        return "MO-" + System.currentTimeMillis();
    }
}

3.3 记录故障日志(事务提交后触发) 

@Service
public class LogService {
    // 在设备状态更新的事务提交后再记录日志(避免脏数据)
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void logFailure(EquipmentFailureEvent event) {
        System.out.println("[事务日志] 设备故障已记录: " + event.getEquipmentId());
    }
}
@SpringBootTest
public class EquipmentFailureTest {
    @Autowired
    private EquipmentService equipmentService;

    @Test
    public void testCriticalFailure() {
        // 模拟一个 CRITICAL 级别故障
        equipmentService.reportFailure("EQ-001", "电机过热", FailureLevel.CRITICAL);
    }
}

 输出结果

[异步告警] 设备ID: EQ-001 发生故障!详情: 电机过热
[生成工单] 设备ID: EQ-001, 工单号: MO-1628761234567
[事务日志] 设备故障已记录: EQ-001

关键点解释

  1. 条件监听
    @EventListener(condition = "#event.level.name() == 'CRITICAL'") 使用 SpEL 表达式过滤事件,只有满足条件的故障才会生成工单。

  2. 事务事件监听
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) 确保日志记录在设备状态更新的事务提交后执行,避免记录无效数据。

  3. 异步处理
    @Async 注解让告警逻辑在独立线程中执行,避免阻塞主业务流程。

你可能感兴趣的:(java,jvm,开发语言)