全书目录

第三十七篇:Symfony 完全指南 —— 组件化政务城区宇宙

第十二章:EventDispatcher 和 Messenger,不是一回事

1 分钟 150 字 第 709 / 962 个阅读单元

很多人会把 Symfony 的事件系统和消息系统混成一坨。

这是很典型的误区。

在政务城区里,它们应该这样理解:

text
EventDispatcher
= 内部广播系统
= “某件事发生了,相关部门自己听”

Messenger
= 公文流转中心
= “这件事要不要排队、异步、跨进程处理”

先看一个消息对象:

php
<?php

namespace App\Message;

final readonly class PermitSubmittedMessage
{
    public function __construct(
        public int $permitId,
    ) {
    }
}

再看处理器:

php
<?php

namespace App\MessageHandler;

use App\Message\PermitSubmittedMessage;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
final class PermitSubmittedMessageHandler
{
    public function __construct(
        private LoggerInterface $logger,
    ) {
    }

    public function __invoke(PermitSubmittedMessage $message): void
    {
        $this->logger->info('开始异步处理营业许可申请', [
            'permit_id' => $message->permitId,
        ]);

        // 发邮件、发短信、生成 PDF、推送审核系统……
    }
}

然后把它路由到异步通道:

yaml
framework:
    messenger:
        transports:
            async: '%env(MESSENGER_TRANSPORT_DSN)%'
        routing:
            App\Message\PermitSubmittedMessage: async

最后启动后台专办员:

bash
php bin/console messenger:consume async

所以两者的区别要钉死:

text
Event
= 广播“发生了什么”

Message
= 指明“请处理这件事”

Messenger
= 决定这件事同步做,还是丢给后台专办员慢慢做

这就是 Symfony 很适合复杂后台、审批流、通知链、异步集成系统的原因之一。