当前位置: 首页 > 知识库问答 >
问题:

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

欧阳英彦
2024-04-26

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

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

// 方法上使用@Retryable(listeners = {"myRetryListener"}, value = Exception.class)// 配置@Configurationpublic class ListenerConfig {    @Bean    public MyRetryListener myRetryListener() {        return new MyRetryListener();    }}

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

共有1个答案

姬温文
2024-04-26

在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中的逻辑。

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

 类似资料:
  • 登录,注销-一切正常,但我不知道如何注册一个AuthentiationListener来记录我的用户。 我使用的是Guice,并且我使用自己的dbsaltwarerealm(公共类dbsaltarerealm扩展了授权领域) 感谢

  • 本文向大家介绍详解vuex 中的 state 在组件中如何监听,包括了详解vuex 中的 state 在组件中如何监听的使用技巧和注意事项,需要的朋友参考一下 前言 不知道大家有没有遇到过这样一种情况? vuex中的state会在某一个组建中使用,而这个状态的初始化是通过异步加载完成的。组件在渲染过程中,获取的state状态为空。也就是说组件在异步完成之前就已经完成渲染了,导致组件的数据没有来得及

  • 我正在处理一些奇怪的遗留代码。他们有一个实现JPanel的自定义对象。这个< code>JPanel对象是主应用程序中的第二个弹出屏幕。我遇到的问题是检测辅助弹出屏幕何时关闭。 我尝试为该类实现一个,但是当我尝试添加它时,没有与此对象关联的。我假设这是因为他们正在使用一个自定义对象,它是一个嵌入式弹出屏幕。 我尝试使用以下命令检索: 这在上失败。我不知道为什么在这个页面上检测右上角的“x”关闭按钮

  • 26.6 注解驱动的监听端点 异步接收消息的最简单的方法是使用注解监听端点的基础架构。简而言之,它允许你暴露托管一个 bean 的方法作为一个 JMS 的监听端点。 @Component public class MyService { @JmsListener(destination = "myDestination") public void processOrder(String da

  • 最后,正如你所看到的,我的游戏同时处理全屏模式和窗口模式。这两个问题都发生。

  • 我有一个基本回收适配器,如下所示: : 基本视图保持架为: 假设ViewHolder有两个视图,一个TextView和一个ImageView。如何对ViewHolder的itemview中的所有项目实现ClickListener