Laravel 事件系统:用领域事件与监听器解耦业务与异步通知
test12026-09-130 次阅读
问题背景
下单支付成功后,常常要同时做发通知、同步 ERP、记日志等好几件事。若把这些逻辑全堆在控制器里,代码会迅速膨胀且难以测试。Laravel 的事件系统把"发生了什么"(事件)和"发生之后做什么"(监听器)分离,天然支持异步与广播。
定义事件
// app/Events/OrderPaid.php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use App\Models\Order;
class OrderPaid
{
use Dispatchable;
public function __construct(public Order $order) {}
}
监听器
// app/Listeners/SendOrderNotification.php
namespace App\Listeners;
use App\Events\OrderPaid;
use App\Notifications\OrderPaidNotify;
class SendOrderNotification
{
public function handle(OrderPaid $event): void
{
$event->order->user->notify(new OrderPaidNotify($event->order));
}
}
注册监听
// app/Providers/EventServiceProvider.php
protected $listen = [
OrderPaid::class => [
SendOrderNotification::class,
\App\Listeners\SyncToErp::class,
],
];
触发与异步
// 在支付回调里
use App\Events\OrderPaid;
OrderPaid::dispatch($order);
// 让监听器异步执行:实现 ShouldQueue
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
class SyncToErp implements ShouldQueue
{
public function handle(OrderPaid $event): void
{
// 推送到 ERP,失败自动进队列重试
}
}
要点
- 事件名用"过去式"(OrderPaid)表达已发生的事实,语义清晰。
- 实现 ShouldQueue 的监听器会自动进 Laravel 队列,失败可重试,不阻塞主流程。
- 需要实时推前端时,让事件实现 ShouldBroadcast,监听器之外的客户端也能收到。
- 事件越细粒度越好,监听器可独立增删,业务改动不影响触发方。
T
test1
文章作者
问题背景 下单支付成功后,常常要同时做发通知、同步 ERP、记日志等好几件事。若把这些逻辑全堆在控制器里,代码会迅速膨...
- 分类
- 技术
- 发布时间
- 2026-09-13
- 字数
- 约 1324 字
- 阅读
- 0 次
