Search code examples
springspring-bootspring-amqpspring-rabbit

Update from Spring Boot 1.5.x to 2.2.x RabbitMQ doesn't declare bindings with a list


I used to declare queues, exchanges and bindings in one of my configuration files as follows:

@EnableRabbit
@Configuration
public class MyRabbitConfiguration {

    @Bean
    public FanoutExchange firstExchange() {
        return new FanoutExchange("firstExchange");
    }

    @Bean
    public Queue firstQueue() {
        return new Queue("firstQueue", true, false, false);
    }

    @Bean
    public FanoutExchange secondExchange() {
        return new FanoutExchange("secondExchange");
    }

    @Bean
    public Queue secondQueue() {
        return new Queue("secondQueue", true, true, true);
    }

    @Bean
    public List<Declarable> bindings() {
        return Arrays.asList(
                BindingBuilder.bind(firstQueue()).to(firstExchange()),
                BindingBuilder.bind(secondQueue()).to(secondExchange()));
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }
}

And this used to work pretty well. After updating from Spring Boot 1.5.x (obviously the starters as well) to Spring Boot 2.2.x, everything still work, except for Bindings. When I replace:

@Bean
public List<Declarable> bindings() {
    return Arrays.asList(
            BindingBuilder.bind(firstQueue()).to(firstExchange()),
            BindingBuilder.bind(secondQueue()).to(secondExchange()));
}

with:

@Bean
public Binding firstBinding() {
    return BindingBuilder.bind(firstQueue()).to(firstExchange());
}

@Bean
public Binding secondBinding() {
    return BindingBuilder.bind(secondQueue()).to(secondExchange());
}

it starts to work as I expect and I still have my Bindings. I suspect it has something to do with this, but couldn't figure out. What am I doing wrong?


Solution

  • You need to use Declarables instead.

    See docs: https://docs.spring.io/spring-amqp/docs/2.2.5.RELEASE/reference/html/#collection-declaration

    Pay attention to the IMPORTANT block:

    In versions prior to 2.1, you could declare multiple Declarable instances by defining beans of type Collection<Declarable>. This can cause undesirable side effects in some cases, because the admin has to iterate over all Collection<?> beans. This feature is now disabled in favor of Declarables, as discussed earlier in this section. You can revert to the previous behavior by setting the RabbitAdmin property called declareCollections to true.