0

I am just wondering whether we can create a meta-annotation and reuse it everywhere. For example, I have an annotation like so:

@QueueBinding(value = @Queue, exchange = @Exchange(value = "MY_FANOUT_EXCHANGE", type = ExchangeTypes.FANOUT))

I need to use it in multiple places. I just want to simplify it something like:

@MyFanoutExchangeBinding = @QueueBinding(value = @Queue, exchange = @Exchange(value = "MY_FANOUT_EXCHANGE", type = ExchangeTypes.FANOUT))

and then use the @MyFanoutExchangeBinding on methods everywhere. If I understand annotations correctly, its not possible. Or is it?

falcon
  • 1,332
  • 20
  • 39

1 Answers1

2

Meta annotations won't work in this context since the @RabbitListener bindings property is a QueueBinding[] and annotations don't have inheritance.

To implement it would need a customized RabbitListenerAnnotationBeanPostProcessor but, since it can't be done in a generic way, I don't think it can be part of the framework, at least in the way you describe.

We might be able to reduce the boilerplate in some other way though; feel free to open a JIRA issue and we can take a look at what might be possible.

EDIT

After receiving the JIRA Issue I thought about it some more and you can achieve your desired results using a custom listener annotation, meta-annotated with @RabbitListener ...

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@RabbitListener(bindings = @QueueBinding(
        value = @Queue,
        exchange = @Exchange(value = "test.metaFanout", type = ExchangeTypes.FANOUT, autoDelete = "true")))
public @interface MyAnonFanoutListener {
}

public static class MetaListener {

    @MyAnonFanoutListener
    public void handle1(String foo) {
        ...
    }

    @MyAnonFanoutListener
    public void handle2(String foo) {
        ...
    }

}

Each listener will get an anonymous, auto-delete, queue bound to the fanout exchange.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Is it possible to use meta annotations for @RabbitListener and pass down the "key" attribute for the nested @QueueBinding? Basically want to share boilerplate RabbitListener / QueueBinding definitions for a topic exchange but allow the user to pass in the routing key to the custom annotation which would then be set on the RabbitListeners QueueBinding – Devin Jett Mar 31 '21 at 05:56
  • No; you can't do that; the only thing you can do is `key="${some.property}"` and set a property - but you'd be limited to one per application. It would be better to declare the queue and binding as `@Bean`s instead of using `@QueueBinding`. – Gary Russell Mar 31 '21 at 13:06
  • Thanks for the quick reply – Devin Jett Mar 31 '21 at 17:43