Issue
When writing web application with Spring Boot you can declare your beans to be part of the session- or request scope.
Is it possible to create a scope for injection of data with messages received by a @RabbitListener?
When receiving a message with a the RabbitListener, I would like to initialize some metadata which I would like to have available for injection in code called during message processing. (e.g. receiving queue for logging, or a pre-configured factory where the configuration depends on parameters known at receiving time of the message).
Passing this data through all called methods feels just ugly.
Ways I could think of, but don't know how to do it:
- AOP
- Custom scopes
Help is greatly appreciated!
Solution
Probably the simplest approach would be to use a MessagePostProcessor
(add to the container/container factory via the afterReceivePostProcessors
property).
/**
* Set {@link MessagePostProcessor}s that will be applied after message reception, before
* invoking the {@link MessageListener}. Often used to decompress data. Processors are invoked in order,
* depending on {@code PriorityOrder}, {@code Order} and finally unordered.
* @param afterReceivePostProcessors the post processor.
* @since 1.4.2
*/
public void setAfterReceivePostProcessors(MessagePostProcessor... afterReceivePostProcessors) {
Assert.notNull(afterReceivePostProcessors, "'afterReceivePostProcessors' cannot be null");
Assert.noNullElements(afterReceivePostProcessors, "'afterReceivePostProcessors' cannot have null elements");
this.afterReceivePostProcessors = MessagePostProcessorUtils.sort(Arrays.asList(afterReceivePostProcessors));
}
Use a ThreadLocal
to store the metadata; you can then access the metadata in the listener.
Answered By - Gary Russell
Answer Checked By - Katrina (JavaFixing Volunteer)