如何在Spring Retry的@Retryable注解中指定监听器??

问题:自定义的MyRetryListener,想在@Retryable中指定使用,现在却变成了不指定也会调用

显现:现在直接写@Retryable不声明listeners 也会走到MyRetryListener中去

// 方法上使用
@Retryable(listeners = {"myRetryListener"}, value = Exception.class)

// 配置

@Configuration
public class ListenerConfig {

    @Bean
    public MyRetryListener myRetryListener() {
        return new MyRetryListener();
    }

}

希望结果,只在注解中指定了listeners = {"myRetryListener"}的时候调用MyRetryListener中的方法

阅读 433
avatarAI BotBETA

在Spring Retry中,@Retryable 注解中的 listeners 属性是用来指定哪些监听器需要在重试事件发生时被调用的。这些监听器应该实现 RetryListener 接口,该接口包含了一些方法,比如 beforeRetryafterRetry 等,这些方法会在重试的不同阶段被调用。

你遇到的问题可能是由于MyRetryListener实现了RetryListener接口,并且你已经在配置中定义了这个bean,所以Spring会自动将其注册为全局的监听器。这意味着,无论是否在@Retryable注解中指定了listeners,只要发生了重试,MyRetryListener中的方法都会被调用。

如果你想要MyRetryListener只在@Retryable注解中指定了listeners属性时才被调用,你可以考虑以下几种解决方案:

  1. 创建多个监听器:你可以创建一个新的监听器,比如ConditionalRetryListener,这个监听器只在@Retryable注解中指定了listeners属性时才被调用。而MyRetryListener则作为全局监听器,始终被调用。
  2. 在监听器中添加条件判断:在MyRetryListenerbeforeRetryafterRetry等方法中,你可以添加条件判断,检查当前方法上是否指定了listeners属性,如果没有,则不执行任何操作。
  3. 使用编程式重试:如果你对声明式重试的灵活性不满意,你可以考虑使用编程式重试。这样,你可以在代码中显式地控制何时调用MyRetryListener

下面是一个使用条件判断的解决方案的示例:

public class MyRetryListener implements RetryListener {

    @Autowired
    private AnnotationUtils annotationUtils;

    @Override
    public <T, E extends Throwable> void beforeRetry(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        Method method = annotationUtils.getMethodFromContext(context);
        if (method != null && method.isAnnotationPresent(Retryable.class)) {
            Retryable retryable = method.getAnnotation(Retryable.class);
            if (Arrays.stream(retryable.listeners()).anyMatch(listener -> "myRetryListener".equals(listener))) {
                // 在这里执行你的逻辑
            }
        }
    }

    @Override
    public <T, E extends Throwable> void afterRetry(RetryContext context, RetryCallback<T, E> callback, Throwable throwable, long attempt, boolean succeeded) {
        // 同上
    }
}

这个示例中,AnnotationUtils是一个自定义的工具类,用于从RetryContext中提取当前正在执行的方法。然后,我们检查该方法上是否存在@Retryable注解,并且listeners属性中是否包含"myRetryListener"。如果条件满足,我们才执行MyRetryListener中的逻辑。

请注意,这只是一个示例,你可能需要根据你的具体需求进行调整。另外,由于这种方法依赖于反射,可能会对性能产生一定的影响。如果性能是一个关键因素,你可能需要考虑其他解决方案。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏