Configuring Multiple RabbitMQ Instances in a Single Spring Boot Application

1. Configuration File (application.yml)

spring:
  rabbitmq:
    primary:
      host: localhost
      port: 5672
      username: guest
      password: guest
      virtualHost: /channel-demo
    secondary:
      host: 192.168.1.184
      port: 5672
      username: guest
      password: guest
      virtualHost: /third-party-test

2. Configuration Classes

Both configuration classes extend a shared abstract base class that provides the connectionFactory() method using the prefix defined by @ConfigurationProperties.

Base Configuration

// AbstractRabbitConfig.java (not shown in original but implied)
// It should use RabbitProperties or manual connection creation via CachingConnectionFactory.
// For brevity, assume it reads properties and returns a CachingConnectionFactory.

Primary RabbitMQ Configuraton

@Configuration
@ConfigurationProperties("spring.rabbitmq.primary")
public class PrimaryRabbitConfig extends AbstractRabbitConfig {

    @Bean(name = "primaryConnectionFactory")
    @Primary
    public ConnectionFactory primaryConnectionFactory() {
        return super.connectionFactory();
    }

    @Bean(name = "primaryRabbitTemplate")
    @Primary
    public RabbitTemplate primaryRabbitTemplate(
            @Qualifier("primaryConnectionFactory") ConnectionFactory connectionFactory) {
        return new RabbitTemplate(connectionFactory);
    }

    @Bean(name = "primaryListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory primaryListenerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("primaryConnectionFactory") ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean(name = "primaryRabbitAdmin")
    @Primary
    public RabbitAdmin primaryRabbitAdmin(
            @Qualifier("primaryConnectionFactory") ConnectionFactory connectionFactory) {
        RabbitAdmin admin = new RabbitAdmin(connectionFactory);
        admin.declareExchange(primaryExchange());
        admin.declareQueue(primaryQueue());
        admin.declareBinding(primaryBinding());
        return admin;
    }

    @Bean
    public DirectExchange primaryExchange() {
        return new DirectExchange("primary-direct-exchange");
    }

    @Bean
    public Queue primaryQueue() {
        return new Queue("primary-queue");
    }

    @Bean
    public Binding primaryBinding() {
        return BindingBuilder.bind(primaryQueue()).to(primaryExchange()).with("primary-routing-key");
    }
}

Secondary RabbitMQ Configuration

@Configuration
@ConfigurationProperties("spring.rabbitmq.secondary")
public class SecondaryRabbitConfig extends AbstractRabbitConfig {

    @Bean(name = "secondaryConnectionFactory")
    public ConnectionFactory secondaryConnectionFactory() {
        return super.connectionFactory();
    }

    @Bean(name = "secondaryRabbitTemplate")
    public RabbitTemplate secondaryRabbitTemplate(
            @Qualifier("secondaryConnectionFactory") ConnectionFactory connectionFactory) {
        return new RabbitTemplate(connectionFactory);
    }

    @Bean(name = "secondaryListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory secondaryListenerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("secondaryConnectionFactory") ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean(name = "secondaryRabbitAdmin")
    public RabbitAdmin secondaryRabbitAdmin(
            @Qualifier("secondaryConnectionFactory") ConnectionFactory connectionFactory) {
        RabbitAdmin admin = new RabbitAdmin(connectionFactory);
        // Optionally declare secondary exchange/queue/binding if needed
        // admin.declareExchange(...)
        return admin;
    }
}

3. Producer

Use the appropriate RabbitTemplate bean to send messsages to the primary RabbitMQ.

@Component
@Slf4j
public class MessageProducer {

    @Autowired
    @Qualifier("primaryRabbitTemplate")
    private RabbitTemplate primaryTemplate;

    public void sendPrimaryMessage() {
        primaryTemplate.convertAndSend("primary-direct-exchange", "primary-routing-key", "Hello from primary");
        log.info("Primary message sent successfully");
    }
}

4. Consumer

Use @RabbitListener with the containerFactory attribute pointing to the specific listener factory bean.

@Component
@Slf4j
public class MessageConsumer {

    @RabbitListener(queues = {"primary-queue"}, containerFactory = "primaryListenerContainerFactory")
    @RabbitHandler
    public void handlePrimaryMessage() {
        System.out.println("Primary queue received a message");
    }

    // For secondary, define another listener if needed
    // @RabbitListener(queues = {"secondary-queue"}, containerFactory = "secondaryListenerContainerFactory")
    // @RabbitHandler
    // public void handleSecondaryMessage() { ... }
}

With this setup, you can manage different RabbitMQ instances independently within the same Spring Boot application. The @Primary annotation ensures that the primary connection is used by default when no qualifier is specified, while the secondary instance can be accessed via explicit @Qualifier references.

Tags: Spring Boot RabbitMQ java Message Queue configuration

Posted on Mon, 18 May 2026 16:45:05 +0000 by friday_13