用途
本技能提供 Laravel 事件驱动架构(Event-Driven Architecture)的最佳实践,用于将应用中的副作用与核心业务逻辑解耦。通过事件(Events)与监听器(Listeners)机制,一个动作可以触发多个相互独立的处理流程,例如发送邮件、生成发票、更新库存、写入分析数据等。
主要能力
事件类结构
事件是简单的数据载体对象,不包含业务逻辑。示例中 OrderPlaced 事件使用 Dispatchable、InteractsWithSockets、SerializesModels 三个 trait,并通过构造函数注入只读的 Order 模型。
监听器类结构
监听器承担单一职责,通过 handle 方法接收事件。示例 SendOrderConfirmation 在 handle 中调用通知逻辑。
自动发现监听器
当监听器位于 App\Listeners 目录且 handle 方法对事件进行了类型提示时,Laravel 会自动发现,无需手动注册。一个监听器也可通过多个方法处理多个事件(如 AuditLogger)。缺少类型提示的 handle 方法不会被自动发现。
事件分发
支持静态分发 OrderPlaced::dispatch($order) 和辅助函数 event(new OrderPlaced($order))。文档明确反对直接调用监听器,因为那会造成紧耦合。
队列监听器
实现 ShouldQueue 接口的监听器会异步执行。可配置 $queue、$tries、$backoff,并实现 failed 方法处理失败,以及 shouldQueue 方法按条件决定是否入队。
事务安全
ShouldQueueAfterCommit:监听器仅在数据库事务提交后才入队。- 事件类上的
$afterCommit = true:事件仅在周围事务提交后才分发,避免监听器处理可能被回滚的数据。
事件订阅者
订阅者类通过 subscribe 方法返回事件与处理方法的映射数组,并在 EventServiceProvider 的 $subscribe 中注册。
模型事件与观察者
观察者(Observer)可处理 creating、created、updating、deleted 等模型生命周期钩子。Laravel 11+ 可通过 #[ObservedBy(OrderObserver::class)] 属性注册。文档建议谨慎使用观察者,仅用于模型生命周期钩子。
事件与直接调用的选择
- 使用事件:一个动作有多个副作用、副作用可能独立变化、副作用可异步执行。
- 使用直接调用:必须一起成功的核心业务逻辑、单一明确职责、需要同步事务保证。
- 不应使用事件:不能静默失败的核心逻辑、需要返回值的场景。
测试事件
使用 Event::fake() 配合 assertDispatched、assertNotDispatched 断言事件分发;可只伪造特定事件让其他监听器正常运行;也可直接调用监听器的 handle 方法进行隔离测试。
使用方式
按照文档中的代码示例定义事件类、监听器类、订阅者和观察者,依赖自动发现机制或手动注册,并通过 dispatch 或 event 辅助函数分发事件。
适用场景
适用于 Laravel 应用中需要解耦副作用的场景,例如订单创建后触发邮件通知、发票生成、库存更新、搜索索引更新等。
限制
文档未提供关于性能开销、版本兼容范围、具体配置项默认值等细节。核心业务逻辑不应隐藏在事件监听器中,事件也不应用于需要返回值的场景。