Home > OS >  Injecting scoped beans in the context of one AMQP message in Spring Boot
Injecting scoped beans in the context of one AMQP message in Spring Boot

Time:02-04

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!

CodePudding user response:

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.

  •  Tags:  
  • Related