Cheat SheetsRabbitMQSpring AMQP

Spring AMQP — Cheat Sheet

RabbitMQ · 4 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
Spring AMQP
RabbitMQ4 topicsQuick revision reference
1

RabbitMQ with Spring AMQP

spring-boot-starter-amqp auto-configures RabbitTemplate and a SimpleMessageListenerContainer; declare Exchanges, Queues, and Bindings as Spring beans.

  • spring-boot-starter-amqp auto-configures ConnectionFactory, RabbitTemplate, and listener container factory
  • Declare Exchange, Queue, Binding as Spring beans — RabbitAdmin creates them on the broker at startup
  • Jackson2JsonMessageConverter enables POJO-based send/receive without manual serialisation
  • @RabbitListener binds a method to a queue; return value is sent to reply-to if present
  • Set AcknowledgeMode.MANUAL and inject Channel + DELIVERY_TAG header for fine-grained ack control
  • Use RetryInterceptorBuilder on the container factory for automatic retry with backoff before DLX
Spring AMQP — topology as Spring beans
@Configuration
class RabbitConfig {

    public static final String ORDER_EXCHANGE = "orders.topic";
    public static final String ORDER_QUEUE    = "orders.created";
    public static final String ROUTING_KEY    = "order.created.#";

    @Bean
    TopicExchange orderExchange() {
        return ExchangeBuilder.topicExchange(ORDER_EXCHANGE)
                .durable(true).build();
    }

    @Bean
    Queue orderQueue() {
        return QueueBuilder.durable(ORDER_QUEUE)
                .withArgument("x-dead-letter-exchange", "orders.dlx")
                .build();
    }

    @Bean
    Binding orderBinding(Queue orderQueue, TopicExchange orderExchange) {
        return BindingBuilder.bind(orderQueue)
                .to(orderExchange)
                .with(ROUTING_KEY);
    }

    // JSON message converter — auto-registered if only one is present
    @Bean
    MessageConverter jacksonConverter() {
        return new Jackson2JsonMessageConverter();
    }
}
2

@RabbitListener

@RabbitListener binds a method to a queue and deserialises the message automatically; supports batching, reply-to, and customisable error handlers with MessageRecoverer.

  • @RabbitListener creates a message listener container that polls queues with one or more consumer threads.
  • Method parameter type drives deserialization — requires a matching MessageConverter bean.
  • @Header injects AMQP message header values into method parameters.
  • ackMode=MANUAL gives full control over ack/nack; default is AUTO (ack on return).
  • @QueueBinding declares exchange, queue, and binding inline — convenient but @Bean config is cleaner.
  • concurrency and maxConcurrency control the thread pool size per listener container.
Java — @RabbitListener variants
// Basic listener — auto-deserialized via MessageConverter
@Component
public class OrderConsumer {

    // Single queue
    @RabbitListener(queues = "order-processor")
    public void onOrder(OrderEvent event) {
        orderService.process(event);  // auto-ack on return
    }

    // Multiple queues
    @RabbitListener(queues = { "orders.uk", "orders.eu" })
    public void onRegionalOrder(OrderEvent event,
            @Header("region") String region) {
        orderService.processForRegion(event, region);
    }

    // Access raw message
    @RabbitListener(queues = "raw-messages")
    public void onRawMessage(Message message) {
        byte[] body = message.getBody();
        MessageProperties props = message.getMessageProperties();
        log.info("Received {} bytes, content-type={}", body.length, props.getContentType());
    }

    // Manual acknowledgement
    @RabbitListener(queues = "critical-orders",
                    ackMode = "MANUAL")
    public void onCritical(OrderEvent event, Acknowledgment ack) {
        try {
            orderService.processCritical(event);
            ack.acknowledge();
        } catch (Exception e) {
            ack.nack(false);   // nack, don't requeue → goes to DLX
        }
    }
}
3

RabbitTemplate

RabbitTemplate provides convertAndSend, convertSendAndReceive (synchronous RPC), and receive/receiveAndConvert for flexible produce/consume operations.

  • Use Jackson2JsonMessageConverter bean to enable JSON serialisation — default SimpleMessageConverter uses Java serialisation
  • convertAndSend is fire-and-forget; convertSendAndReceive blocks until a reply arrives (synchronous RPC over AMQP)
  • MessagePostProcessor lambda in convertAndSend allows setting headers, TTL, priority, and correlation ID per message
  • Publisher confirms verify broker acceptance; mandatory flag returns unroutable messages via callback
  • RabbitTemplate is thread-safe — use as a singleton; do not create per-request instances
  • For async RPC, use AsyncRabbitTemplate which returns CompletableFuture instead of blocking
Java — RabbitTemplate configuration and convertAndSend patterns
// Bean configuration — use Jackson for JSON serialisation
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
    template.setMessageConverter(converter);
    template.setExchange("orders");          // default exchange
    template.setRoutingKey("order.placed");  // default routing key
    return template;
}

// Fire-and-forget publishing
@Service
public class OrderEventPublisher {

    private final RabbitTemplate rabbitTemplate;

    // Simple: uses default exchange and routing key from bean config
    public void publishOrderPlaced(OrderPlacedEvent event) {
        rabbitTemplate.convertAndSend(event);
    }

    // Explicit exchange + routing key
    public void publishOrderShipped(OrderShippedEvent event) {
        rabbitTemplate.convertAndSend("orders", "order.shipped", event);
    }

    // With MessagePostProcessor — set custom headers
    public void publishWithHeaders(OrderEvent event, String correlationId) {
        rabbitTemplate.convertAndSend("orders", "order.placed", event, msg -> {
            msg.getMessageProperties().setCorrelationId(correlationId);
            msg.getMessageProperties().setHeader("X-Source", "order-service");
            msg.getMessageProperties().setExpiration("30000"); // 30s TTL
            return msg;
        });
    }
}
4

Spring Retry with RabbitMQ

Configure a RetryInterceptorBuilder on the listener container to automatically retry failed messages with back-off before routing to a DLQ.

  • Spring Retry interceptor on the listener container provides in-process retries before routing to DLQ
  • RejectAndDontRequeueRecoverer nacks the message after exhausted retries → broker routes to Dead Letter Queue
  • RepublishMessageRecoverer publishes to a specific error exchange with stack trace headers — useful for structured DLQ analysis
  • Exponential back-off (1s, 2s, 4s) prevents hammering a struggling downstream service with rapid retries
  • In-process retry is for transient errors (seconds); DLQ + TTL queue loop is for longer retry delays (minutes/hours)
  • ImmediateRequeueMessageRecoverer requeues immediately — dangerous, can cause infinite hot loops on non-transient errors
Java — RetryInterceptorBuilder with exponential back-off and DLQ fallback
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

// Listener container factory with retry + exponential back-off
@Bean
public SimpleRabbitListenerContainerFactory retryListenerContainerFactory(
        ConnectionFactory connectionFactory,
        MessageConverter messageConverter) {

    SimpleRabbitListenerContainerFactory factory =
        new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setMessageConverter(messageConverter);
    factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); // manual ack

    // Exponential back-off retry: 1s, 2s, 4s, 8s — then send to DLQ
    RetryInterceptorBuilder<?> retryBuilder = RetryInterceptorBuilder.stateless()
        .maxAttempts(4)
        .backOffOptions(1000, 2.0, 8000)  // initialInterval, multiplier, maxInterval
        .recoverer(new RejectAndDontRequeueRecoverer());
        // After 4 attempts: NACK with requeue=false → message goes to DLQ

    factory.setAdviceChain(retryBuilder.build());
    return factory;
}

// Listener — exceptions trigger retry automatically
@RabbitListener(queues = "order.processing",
                containerFactory = "retryListenerContainerFactory")
public void processOrder(OrderMessage order) {
    // If this throws, Spring Retry catches it and retries
    // After maxAttempts: RejectAndDontRequeueRecoverer sends to DLQ
    orderService.process(order);
}
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/rabbitmq