在使用Spring的Retry注解时候,难免会遇到如标题中的报错。该错误就是找不到对应的补偿方法而导致的错误。那么,请确定你的程序:
- @Retryable 和 @Recover 所注解的方法是否都是某个接口的方法实现,如果是,使用 @EnableRetry(proxyTargetClass = true) 。 proxyTargetClass=true会使用cglib进行代理。(注意:一般都不是该问题。@Recover也可以不用在接口中声明,直接在实现类中编写即可)
- @Retryable 和 @Recover 是否有写在同一个类里面?需要在同一个类里面
- @Recover 方法第一个参数是否为Throwable异常?第一个参数需要是Throwable异常
- @Retryable 和 @Recover 方法返回值是否不一致?除去第一个异常参数不谈,有其他参数的话需要保持一致
- 对 @Recover 注解的作用是否有理解上的偏差。@Recover 注解的方法是补偿方法,并不是一定要重试之后才进入,只要被 @Retryable 注解的方法抛异常都会进入 @Recover 注解的方法里进行补偿。所以这就要求如果你只希望对某个异常进行重试,但你的 @Retryable 注解的方法又同时会抛出其他异常,这个时候你需要写一个支持所有异常的 @Recover 方法或者分为重试异常的和所有异常的两个 @Recover 方法。如下:
import org.springframework.retry.annotation.EnableRetry;
/**
* 启动器.
*/
@EnableRetry(proxyTargetClass = true)
@SpringCloudApplication
public class DemoApplication {
...
}
/**
* 接口.
*/
public interface IDemo {
/**
* 需要重试的方法.
*/
void retry(int num)
/**
* 除数为0异常补偿方法.
*/
void rcoverWithZero(ArithmeticException e, int num)
/**
* 其他所有异常补偿方法.
*/
void recover(Exception e, int num)
}
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
/**
* 接口实现.
*/
public class DemoImpl implements IDemo {
/**
* 需要重试的方法.
*/
@Override
@Retryable(
value = InvalidArgumentException.class,
maxAttempts = 3,
backoff = @Backoff(delay = 1000L, multiplier = 1.5)
)
public void retry(int num) throws InvalidArgumentException {
if (num == 0) {
throw new InvalidArgumentException(new String[] {});
}
int i = num / 0;
}
/**
* 除数为0异常补偿方法.
*/
@Override
@Recover
public void rcoverWithZero(ArithmeticException e, int num) {
System.out.println("ArithmeticException异常重试次数过后依旧报错的补偿方法");
}
/**
* 其他所有异常补偿方法.
*/
@Override
@Recover
public void recover(Exception e, int num) {
System.out.println("非ArithmeticException异常的补偿方法");
}
}
作者有话说:如果有幸帮助到你,麻烦给个赞,给个收藏,给个关注,感谢!你的赞,收藏和关注是我的动力源泉