Spring AMQP - Sender and Receiving Messages
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Spring AMQP is the Spring abstraction most commonly used with RabbitMQ to send and receive messages without writing low-level client code everywhere. A basic setup needs three things: broker infrastructure, a sender, and a listener. The harder part is not sending the first message. It is deciding how messages are routed, serialized, retried, and handled when consumers fail.
Define Queue, Exchange, and Binding Clearly
A lot of examples send directly to a queue, but explicit exchanges and bindings scale better because routing stays visible.
This keeps queue names and routing keys explicit and avoids hidden broker assumptions.
Send Messages with RabbitTemplate
For sending, Spring AMQP uses RabbitTemplate.
convertAndSend is convenient because it works with Spring’s message converters rather than forcing you to serialize manually in every sender.
Prefer JSON Payloads Over Java Serialization
For most service-to-service messaging, JSON is easier to inspect and safer to integrate than default Java serialization.
With that in place, a compact payload type works well.
That keeps the on-the-wire message readable and makes cross-service integration much easier.
Receive Messages with @RabbitListener
The consumer side is usually implemented with @RabbitListener.
Spring creates the listener container, subscribes to the queue, and invokes your method when a message arrives.
Think About Failure Handling Early
Messaging design becomes serious when processing can fail. A consumer that crashes after updating one table but before finishing all side effects may see the same message again. That means message handlers should generally be idempotent or at least duplicate-safe.
You should also decide what happens after repeated failures. A message should not usually loop forever with no observability. Dead-letter queues, retry policies, and alerting are part of the design, not optional cleanup.
The sender and receiver code may look simple, but the production behavior is defined by these operational choices.
Keep Business Logic Out of Messaging Glue
A healthy Spring AMQP design keeps infrastructure in configuration classes, publishing in sender services, and business logic in application services called by listeners. If the listener method grows into a large transaction script, the messaging layer becomes hard to test and harder to reason about.
The listener should usually validate the message shape, call a service, and let that service own the business workflow.
Common Pitfalls
- Sending directly to queues everywhere and never defining exchanges or routing explicitly.
- Using Java object serialization when a JSON payload would be easier to inspect and integrate.
- Putting too much domain logic directly inside listener methods.
- Ignoring idempotency and assuming messages are processed exactly once.
- Leaving failures in endless redelivery loops without a retry or dead-letter strategy.
Summary
- Spring AMQP typically uses queues, exchanges, and bindings plus a sender and listener.
- '
RabbitTemplatepublishes messages, and@RabbitListenerconsumes them.' - JSON conversion is usually a better default than Java serialization.
- Reliable messaging requires thought about retries, duplicates, and dead-letter behavior.
- Keep the messaging layer thin and let application services own the business work.

