# 📡 Spring 事件机制

### 🎉 事件发布演示

模拟用户登录事件，观察事件发布和监听过程

等待事件发布...

## 🔄 事件机制流程

发布者 → ApplicationEventPublisher → 事件 → 监听者
核心优势：

- 解耦：发布者和监听者互不依赖
- 扩展：新增监听器无需修改发布者
- 异步：耗时操作不阻塞主流程

## 💻 代码实现

### 1. 定义事件

    public class UserEvent {
        public enum Type { CREATED, UPDATED, DELETED, LOGIN }

        private Type type;
        private Long userId;
        private String userName;
        private LocalDateTime timestamp;

        // constructor, getters...
    }

### 2. 发布事件

    @Component
    public class UserEventPublisher {

        @Autowired
        private ApplicationEventPublisher eventPublisher;

        public void publishUserLogin(Long userId, String userName) {
            UserEvent event = new UserEvent(
                UserEvent.Type.LOGIN,
                userId,
                userName,
                "用户登录成功"
            );
            eventPublisher.publishEvent(event);
        }
    }

### 3. 监听事件

    @Component
    public class UserEventListener {

        // 基础监听
        @EventListener
        public void handleUserEvent(UserEvent event) {
            System.out.println("收到事件: " + event.getType());
        }

        // 条件监听 - 只处理登录事件
        @EventListener(condition = "#event.type == T(com.example.demo.model.UserEvent$Type).LOGIN")
        public void handleLogin(UserEvent event) {
            System.out.println("用户登录: " + event.getUserName());
        }

        // 异步监听 - 不阻塞主流程
        @Async
        @EventListener
        public void sendWelcomeEmail(UserEvent event) {
            // 发送邮件...
        }
    }

### 4. 控制器中使用

    @RestController
    @RequestMapping("/aop")
    public class AopEventController {

        @Autowired
        private UserEventPublisher eventPublisher;

        @PostMapping("/event/publish")
        public Map<String, Object> publishEvent(
                @RequestParam Long userId,
                @RequestParam String userName) {

            // 发布事件
            eventPublisher.publishUserLogin(userId, userName);

            return Map.of(
                "message", "事件已发布",
                "userId", userId,
                "userName", userName
            );
        }
    }

## 🎯 应用场景

场景 | 事件类型 | 处理逻辑
--- | --- | ---
用户注册 | UserCreatedEvent | 发送欢迎邮件、初始化数据
订单创建 | OrderCreatedEvent | 扣库存、发送通知
支付成功 | PaymentSuccessEvent | 更新订单状态、发送短信
用户登录 | UserLoginEvent | 记录登录日志、更新在线状态

### 💡 最佳实践

- 事件类应该是不可变的（只读属性）
- 使用 `@Async` 处理耗时操作
- 避免在监听器中抛出异常
- 使用 `condition` 过滤不需要的事件
- 复杂场景考虑使用消息队列（RabbitMQ/Kafka）

← 返回学习中心