You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RetryListener的onError方法中从RetryContext获取实现类名称

问题:Spring Retry监听器中获取实现类名称而非抽象类名称

我定义了如下Spring Retry相关代码:

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;

public abstract class ServiceBase {

    @Retryable(value = ServiceException.class, maxAttempts = 3, backoff = @Backoff(delay = 5000), listeners = {"myRetryListener"})
    public void start() throws ServiceException {
        fireServiceStarted("Service started");
    }
}


public class MyRetryListener implements RetryListener {

    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        // Log when retry operation starts
        return true; // proceed with retry
    }

    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        // Log when retry operation ends
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        // Log each error during retry
    }
}

尝试在MyRetryListener的onError方法中从RetryContext获取实现类的名称,但目前获取到的却是抽象类ServiceBase的名称,请问该如何解决?


解决方案

由于@Retryable注解标注在抽象类的方法上,Spring Retry默认关联的是抽象类的信息。要获取实际实现类的名称,可采用以下几种方法:

方法1:从RetryCallback提取目标对象

将RetryCallback强转为MethodInvocationRetryCallback,通过其内部的方法调用信息获取被代理的实际实现类实例:

@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
    if (callback instanceof MethodInvocationRetryCallback) {
        MethodInvocationRetryCallback<T, E> methodCallback = (MethodInvocationRetryCallback<T, E>) callback;
        Object targetObject = methodCallback.getInvocation().getThis();
        String implClassName = targetObject.getClass().getSimpleName();
        // 业务处理:记录或使用实现类名称
        System.out.println("实际实现类:" + implClassName);
    }
}

方法2:在抽象类方法中存入实现类信息到上下文

在抽象类的start方法中,通过@RetryContext注入上下文,将当前实例的类信息存入,监听器直接从上下文读取:
首先修改ServiceBase的start方法:

import org.springframework.retry.annotation.RetryContext;

public abstract class ServiceBase {

    @Retryable(value = ServiceException.class, maxAttempts = 3, backoff = @Backoff(delay = 5000), listeners = {"myRetryListener"})
    public void start(@RetryContext RetryContext context) throws ServiceException {
        // 将实现类名称存入RetryContext
        context.setAttribute("implClassName", this.getClass().getSimpleName());
        fireServiceStarted("Service started");
    }
}

然后在MyRetryListener的onError方法中读取:

@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
    String implClassName = (String) context.getAttribute("implClassName");
    System.out.println("实际实现类:" + implClassName);
}

内容的提问来源于stack exchange,提问作者Sravan Gajula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:03:14