Search code examples
spring-bootrabbitmqspring-amqpspring-rabbit

How to configure the rabbit connection factory but keep the Spring Boot autoconfiguration?


I want to programmatically set the host property on the org.springframework.amqp.rabbit.connection.CachingConnectionFactory. I want to keep the Spring Boot auto-configured defaults and values that come from my application-{profile-name}.yml files for everything else, so for those reasons I don't want to simply create my own CachingConnectionFactory bean.

I found the org.springframework.boot.autoconfigure.amqp.ConnectionFactoryCustomizer class which looks very promising, in that I see how it is called in RabbitAutoConfiguration class to configure the underlying com.rabbitmq.client.ConnectionFactory that is in the spring framework CachingConnectionFactory. But, I'm not sure how to create my ConnectionFactoryCustomizer instance and register it as a callback, and also to do so in a way that it is called in the correct order (called last, I would think).

I tried this, but the connection was still made to "localhost":

@Bean
@Order(Integer.MAX_VALUE)
public ConnectionFactoryCustomizer myConnectionFactoryCustomizer() {
    return factory -> {
        factory.setHost("anotherhost");
    };
}

I also tried this approach, which I was inspired to try from another stackoverflow post with a somewhat similar question: How to set custom name for RabbitMQ connection?

@Bean
public SmartInitializingSingleton configureConnectionFactory(final CachingConnectionFactory factory) {
    factory.setHost("anotherhost");
    return () -> {
        factory.setHost("anotherhost");
    };
}

but neither of these approaches works. The code is being executed that calls factory.setHost so I am obviously doing something wrong. My log output is still this:

2021-10-17 13:45:24,271|INFO||myContainer-3|org.springframework.amqp.rabbit.connection.CachingConnectionFactory|Attempting to connect to: [localhost:5672]

So, what is the correct way to programmatically override values such as host in the connection factory? (before any connections are created, of course)


Solution

  • Boot configures the CachingConnectionFactory.addresses property (which overrides the host).

    Try this...

    @Bean
    @Order(Integer.MAX_VALUE)
    public ConnectionFactoryCustomizer myConnectionFactoryCustomizer() {
        return factory -> {
            factory.setHost("anotherhost");
        };
    }
    
    @Bean
    ApplicationRunner runner(CachingConnectionFactory ccf) {
        ccf.setAddresses(null);
        return args -> {
        };
    }
    

    It can be done in any other bean definition (not necessarily a runner), but it can't be in the myConnectionFactoryCustomizer bean because there is a circular reference.

    Or

    @Bean
    ApplicationRunner runner(CachingConnectionFactory ccf) {
        ccf.setAddresses(null);
        ccf.setHost("another");
        return args -> {
        };
    }