2

Related to How do we hook into before/After message processing using @RabbitListener

If I want to configure RabbitTemplate globally and set MessagePostProcessor, what is the best way?

  1. Should I copy the bean definition from RabbitAutoConfiguration?
  2. Or should I intercept the bean definition using BeanPostProcessor?

The problem with first solution is that, RabbitTemplate in RabbitAutoConfiguration is not just bounding the properties to the bean instance but also set message converts:

MessageConverter messageConverter = this.messageConverter.getIfUnique();
if (messageConverter != null) {
    template.setMessageConverter(messageConverter);
}

So, should I duplicate this logic as follows, or just follow the second option of BeanPostProcessor as in Sleuth?

@ConfigurationProperties(prefix = "spring.rabbitmq.template")
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,
                                     ObjectProvider<MessageConverter> messageConverterObjectProvider) {

    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    MessageConverter messageConverter = messageConverterObjectProvider.getIfUnique();
    if (messageConverter != null) {
        template.setMessageConverter(messageConverter);
    }
    template.setBeforePublishPostProcessors(myBeforePublishMPP());
    return template;
}
Muhammad Hewedy
  • 29,102
  • 44
  • 127
  • 219

2 Answers2

1

I would say there is just enough to @Autowired an auto-configured RabbitTemplate and inject your MessagePostProcessor into that RabbitTemplate:

@Autowired
private RabbitTemplate rabbitTemplate;

@PostConstruct
public void init() {
    this.rabbitTemplate.setBeforePublishPostProcessors(myMessagePostProcessor());
}

@Bean
public MessagePostProcessor myMessagePostProcessor() {
    return message -> null;
}
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Yes it works, but I think will need to put this post-construct method in every service injecting the rabbitTemplate. (according to https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java#L207) – Muhammad Hewedy Nov 29 '18 at 20:47
  • 1
    No, that's not. The `RabbitTemplate` is a *singleton* bean, therefore it is enough to mutate it only once. All other places will get it already with your post-processor. – Artem Bilan Nov 29 '18 at 20:57
1

I would do it the first way so the application.properties are applied, but change the method signature to receive the ObjectProvider< MessageConverter> like they do in Sleuth.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179