⌂ Index
Kapitel 20 · Messaging

Spring AMQP und RabbitMQ

Typ: LibraryVersion 2 ausführlich

Spring AMQP überträgt Spring-Konzepte auf AMQP/RabbitMQ mit RabbitTemplate, Listenern, Exchange/Queue-Konfiguration und Message Conversion.

Fachliche Einordnung

RabbitMQ eignet sich für Arbeitsqueues, Routing, Delayed Processing und klassische Message-Broker-Szenarien. Es unterscheidet sich bewusst von Kafka-Eventlogs.

Enterprise-Merksatz: Spring AMQP überträgt Spring-Konzepte auf AMQP/RabbitMQ mit RabbitTemplate, Listenern, Exchange/Queue-Konfiguration und Message Conversion.

Technische Darstellung

Publisher Exchange Binding Queue Listener DLX
Kernkonzepte
  • Exchange, Queue und Binding.
  • RabbitTemplate für Publisher.
  • @RabbitListener für Consumer.
  • MessageConverter und RetryInterceptor.
  • Dead Letter Exchange und TTL.
Wann einsetzen?
  • Du brauchst Work Queues oder Routing nach Topic/Headers.
  • Du migrierst JMS-artige Queue-Kommunikation.
  • Du willst einfache, robuste asynchrone Jobs.
Typische Fehler und Risiken
  • RabbitMQ wie Kafka verwenden wollen.
  • Keine DLQ oder Poison-Message-Strategie.
  • Unbegrenzte Prefetch-Werte erzeugen Speicher-/Fairness-Probleme.
Legacy- und Modernisierungssicht

IBM MQ/JMS Use Cases können oft zu RabbitMQ-Queues migriert werden, sofern Transaktions- und Zustellgarantien neu bewertet werden.

Ausführliches Beispiel

Das Beispiel zeigt bewusst nicht nur Annotationen, sondern auch die Verantwortung der Schicht. In echten Projekten sollte der technische Spring-Code an Adapter- oder Konfigurationsrändern bleiben, während die Fachlogik testbar und möglichst frameworkarm bleibt.

@Configuration
class ShippingAmqpConfiguration {
    @Bean Queue shippingQueue() { return QueueBuilder.durable("shipping.commands").build(); }
    @Bean DirectExchange exchange() { return new DirectExchange("order.exchange"); }
    @Bean Binding binding(Queue shippingQueue, DirectExchange exchange) {
        return BindingBuilder.bind(shippingQueue).to(exchange).with("ship");
    }
}

@Component
class ShippingListener {
    @RabbitListener(queues = "shipping.commands")
    void handle(ShipOrderCommand command) {
        shippingService.ship(command.orderId());
    }
}
Checkliste für Reviews
  • Ist die Verantwortung des Bausteins klar: Framework steuert Lebenszyklus, Library wird gezielt benutzt?
  • Ist die Fachlogik außerhalb von Controller, Listener, Repository-Implementierung oder Konfiguration?
  • Sind Fehlerfälle, Timeouts, Security, Monitoring und Tests sichtbar modelliert?
  • Gibt es klare Grenzen zwischen DTO, Domäne, Persistence und Infrastruktur?