0

I have a code base with several nearly-identical usages of @Retryable, all driven by the same configuration values. So I created a new annotation that's annotated with ("inherits") @Retryable, like this:

@Documented
@Retention(RUNTIME)
@Target({ TYPE, METHOD })
@Retryable(
        include = RestClientException.class,
        maxAttempts = 5,
        backoff = @Backoff(delay = 1000, multiplier = 3)
    )
public @interface RESTClientRetry {

    @AliasFor(annotation = Retryable.class, attribute = "listeners")
    String[] listeners() default {};

    @AliasFor(annotation = Retryable.class, attribute = "include")
    Class<? extends Throwable>[] include() default {};

    @AliasFor(annotation = Retryable.class, attribute = "maxAttemptsExpression")
    String maxAttemptsExpression() default "";

    @AliasFor(annotation = Retryable.class, attribute = "backoff")
    Backoff backoff() default @Backoff();
}

This works as expected, except for when I want usages of this annotation to use their own listeners. Usage is like this:

@RESTClientRetry(listeners = "retryLoggerBean1")

In an application where there are several RetryListener beans (named retryLoggerBean1, retryLoggerBean2, etc), they are all getting called for every method that's annotated with RESTClientRetry, even though each annotation specifies its own listeners.

Using the debugger, I see that when AnnotationAwareRetryOperationsInterceptor is invoked, the Retryable object has an empty value for listeners. So it seems like that interceptor is not supporting annotation "inheritance" (composition). Without any annotation-specific listeners, it's falling back to the global set of listeners, which explains why I'm seeing them all invoked for every method.

Is this a known limitation or bug with the interceptor, or is there another way to wrap @Retryable with my own annotation and still le individual usage define which listener to use?

E-Riz
  • 31,431
  • 9
  • 97
  • 134

1 Answers1

1

This is a limitation of older spring-retry versions (1.2.x), which were written before the @AliasFor annotation existed. 1.3.x versions of spring-retry work as expected with the code in the question.

Thus, the solution is to update to a 1.3.x (or later) version of spring-retry.

E-Riz
  • 31,431
  • 9
  • 97
  • 134