Spring-实现接口时retry找不到recovery方法

Spring-Retry cannot locate recovery method when implement an interface

我在使用 spring 启动 spring-重试时发现问题。 class实现接口时,超过最大重试次数后无法进入@recover方法。但是当我注入一个正常的class时,我可以输入这个method.Your提示帮助和善意的建议将不胜感激,谢谢!

When I do this,I can enter the @Recover method

@Service
public class TestService {

    @Retryable(Exception.class)
    public String retry(String c) throws Exception{
        throw new Exception();
    }

    @Recover
    public String recover(Exception e,String c) throws Exception{
        System.out.println("got error");
        return null;
    }
}

But once the class implement another interface, it's not works

@Service
public class TestService implements TestServiceI{

    @Override
    @Retryable(Exception.class)
    public String retry(String c) throws Exception{
        throw new Exception();
    }

    @Recover
    public String recover(Exception e,String c) throws Exception{
        System.out.println("got error");
        return null;
    }
}

Spring-Retry使用AOP实现@Retry。使用 AOP 时,默认使用 JDK 动态代理。 JDK 动态代理是基于接口的。

这意味着您会得到一个动态创建的 class,它伪装成 TestServiceI 但它不是 TestService。代理不包含 recover 方法(因为它不在界面上),因此 Spring Retry 无法检测到它。

要解决此问题,您需要为 Spring 启用基于 class 的代理,通过将 @EnableRetry 上的 proxyTargetClass 属性设置为 true 重试(请参阅 javadoc).

@EnableRetry(proxyTargetClass=true) 
  1. 标记 proxyTargetClass=true: @EnableRetry(proxyTargetClass = true)
  2. @Recover 方法必须return与原始方法相同的类型;