Java中设计可重试异常应定义RetriableException基类,含shouldRetry字段标识是否重试,并按场景派生子类(如NetworkTimeoutException默认可重试、InvalidParameterException设为不可重试),配合Spring Retry时仅include该基类以精准控制重试范围。

在 Java 中设计带有重试标识的自定义异常,核心是让调用方能明确区分“可重试”和“不可重试”的错误场景,从而指导上层做智能重试决策(比如配合 Spring Retry 或自研重试逻辑)。
定义可重试异常基类
建议定义一个标记接口或基类,统一语义。推荐使用运行时异常基类 + 可重试标识字段:
public class RetriableException extends RuntimeException {
private final boolean shouldRetry;
public RetriableException(String message) {
this(message, true); // 默认可重试
}
public RetriableException(String message, boolean shouldRetry) {
super(message);
this.shouldRetry = shouldRetry;
}
public RetriableException(String message, Throwable cause) {
this(message, cause, true);
}
public RetriableException(String message, Throwable cause, boolean shouldRetry) {
super(message, cause);
this.shouldRetry = shouldRetry;
}
public boolean shouldRetry() {
return shouldRetry;
}
}
这样既保持异常链完整,又可通过 shouldRetry() 明确判断是否应触发重试。
按业务场景派生具体异常
避免所有错误都抛同一个 RetriableException,应按失败原因分类型,提升可读性和处理精度:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
-
网络抖动类:如
NetworkTimeoutException extends RetriableException(默认shouldRetry = true) -
临时资源冲突类:如
OptimisticLockFailureException extends RetriableException(可重试,可能下次版本号对上了) -
明确不可重试类:如
InvalidParameterException extends RetriableException(构造时传false)
与 Spring Retry 集成(可选但常用)
若用 Spring Retry,可通过 @Retryable 的 include 属性指定只对可重试异常生效:
@Retryable(
include = { RetriableException.class },
maxAttempts = 3,
backoff = @Backoff(delay = 1000)
)
public void doSomething() throws RetriableException {
// 可能抛出 NetworkTimeoutException 等
}
注意:不要把 RuntimeException 直接写进 include,否则会误重试 NullPointerException 等编程错误。
使用建议与注意事项
- 重试标识应在异常创建时就确定,不建议运行时动态修改(破坏不可变性)
- 日志中记录
shouldRetry值,方便排查重试行为是否符合预期 - 若底层已有异常(如
IOException),可包装为RetriableException并根据上下文决定是否重试,例如:new RetriableException("HTTP request failed", e, isTransientError(e)) - 避免过度细分——不是每个错误都需要新异常类,优先复用已有语义清晰的子类

















