Home/Learn/RabbitMQ/RabbitMQ with Spring AMQP

RabbitMQ with Spring AMQP

Intermediate
Spring AMQP

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

Overview

Spring AMQP is the Spring abstraction layer over the RabbitMQ Java client. Adding `spring-boot-starter-amqp` to your project auto-configures three key beans: `ConnectionFactory` (connection pool to the broker), `RabbitTemplate` (synchronous send/receive), and `SimpleRabbitListenerContainerFactory` (container that drives `@RabbitListener` consumers). Infrastructure — exchanges, queues, and bindings — is declared as Spring beans of type `Exchange`, `Queue`, and `Binding`; Spring AMQP's `RabbitAdmin` creates them on the broker at startup. `@RabbitListener` turns any Spring bean method into a message consumer. `MessageConverter` (default: `SimpleMessageConverter`; common alternative: `Jackson2JsonMessageConverter`) serialises/deserialises message bodies.

Infrastructure Beans: Exchange, Queue, Binding

Declare your AMQP topology as Spring beans. `RabbitAdmin` detects all `Exchange`, `Queue`, and `Binding` beans in the context and calls the broker's declare APIs on startup. This makes topology reproducible and version-controllable.

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();
    }
}

Sending and Receiving with RabbitTemplate

`RabbitTemplate.convertAndSend()` serialises the payload with the configured `MessageConverter` and publishes it. `@RabbitListener` binds a method to one or more queues. Return values are automatically sent to the `reply-to` queue if present, enabling RPC.

Spring AMQP — publish and consume
// Producer
@Service
@RequiredArgsConstructor
class OrderPublisher {
    private final RabbitTemplate rabbit;

    public void publish(OrderCreatedEvent event) {
        rabbit.convertAndSend(
            RabbitConfig.ORDER_EXCHANGE,
            "order.created.eu",    // routing key
            event                  // serialised by Jackson2JsonMessageConverter
        );
    }
}

// Consumer
@Component
class OrderConsumer {

    @RabbitListener(queues = RabbitConfig.ORDER_QUEUE,
                    containerFactory = "rabbitListenerContainerFactory")
    public void handle(OrderCreatedEvent event, Channel channel,
                       @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        try {
            processOrder(event);
            channel.basicAck(tag, false);
        } catch (RecoverableException e) {
            channel.basicNack(tag, false, true);   // requeue
        } catch (Exception e) {
            channel.basicNack(tag, false, false);  // → DLX
        }
    }
}

Container Configuration: Concurrency & Error Handling

The `SimpleRabbitListenerContainerFactory` controls concurrency, prefetch, ack-mode, and error handling. `DirectMessageListenerContainer` (lower latency, one channel per consumer) is an alternative for high-concurrency scenarios. Attach a `MessageRecoverer` or `RetryInterceptor` to the factory for automatic retry before sending to the DLX.

Spring AMQP — container factory with retry
@Bean
SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
        ConnectionFactory cf, MessageConverter converter) {
    var factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(cf);
    factory.setMessageConverter(converter);
    factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    factory.setPrefetchCount(10);
    factory.setConcurrentConsumers(3);
    factory.setMaxConcurrentConsumers(10);   // auto-scale consumers

    // Retry up to 3 times with exponential backoff, then send to DLX
    factory.setAdviceChain(RetryInterceptorBuilder.stateless()
            .maxAttempts(3)
            .backOffOptions(500, 2.0, 5_000)
            .recoverer(new RejectAndDontRequeueRecoverer())
            .build());
    return factory;
}

Key Points to Remember

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

Interview Questions

Sign in to ask Aria
1

What does spring-boot-starter-amqp auto-configure?

EasyCapgemini
2

How does RabbitAdmin know which exchanges and queues to create on the broker?

MediumAccenture
3

What is the difference between SimpleMessageListenerContainer and DirectMessageListenerContainer?

HardGoldman Sachs
4

How would you configure automatic retry with exponential backoff for a @RabbitListener?

MediumDeliveroo
5

How do you switch from the default SimpleMessageConverter to Jackson-based JSON conversion?

EasyThoughtWorks

Ask Aria about RabbitMQ with Spring AMQP

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…