如何在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
相关产品推荐
相关产品推荐

