如何将Spring @Retryable用作元宣传和支持听众?

发布于 2025-02-03 19:17:22 字数 1506 浏览 3 评论 0原文

我有一个代码库,其中有几乎相同的用法@retryable,这些用法都是由相同的配置值驱动的。因此,我创建了一个新的注释,该注释用(“继承”)@retryable,如下:

@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();
}

这是按预期工作的,除非我希望使用此注释使用他们自己的听众。用法就是这样:

@RESTClientRetry(listeners = "retryLoggerBean1")

在有几个retrylistener bean的应用程序中被称为 restClientRetry注释的每个方法,即使每个注释都指定其自己的侦听器

使用调试器,我看到,调用AnnotationAnotationAnotationAwareRetRyoperationsInterceptor时,可重试对象具有侦听器的空值。因此,似乎该拦截器不支持注释“继承”(组成)。没有任何特定于注释的听众,它将回到全局的听众集中,这解释了为什么我看到他们 all 为每个调用了每个方法。

这是拦截器的已知限制或错误,还是有其他方法可以用我自己的注释将@retryable 包裹,并且仍然可以使用个人用法来定义要使用的侦听器?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谎言 2025-02-10 19:17:22

这是对@aliasfor注释之前写的旧弹簧版本(1.2.x)的限制。 1.3.x版本的春季重新制作,与该问题中的代码一样。

因此,该解决方案是更新为1.3.x(或更高版本)的弹簧重返版本。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文