A Messenger handler is a callable with a type hint

4.3 made Messenger stable, and the registration mechanism is autoconfiguration on an interface — so a handler is a class with one method and no boilerplate.

use SymfonyComponentMessengerHandlerMessageHandlerInterface;

final class SendReceiptHandler implements MessageHandlerInterface
{
    public function __invoke(SendReceipt $message): void
    {
        $this->mailer->send($this->build($message->orderId));
    }
}

// the message it handles is determined by the type hint. that is all.

The message class carries no framework dependency at all, which means it can be shared with a consumer in another application as a plain data object. Several handlers for one message are allowed and all of them run, which is what makes the bus usable for events as well as commands. The type hint being the registration is elegant and has one failure mode: a typo in the class name produces a handler that is never called and never complains.