如何将Spring @Retryable用作元宣传和支持听众?
我有一个代码库,其中有几乎相同的用法@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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是对
@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.