Spring Retry组合retryOn与notRetryOn配置自定义异常重试方法
Spring Retry 组合白/黑名单异常重试规则实现
Spring Retry 原生Builder默认不支持链式同时调用retryOn和notRetryOn,但可以通过自定义异常判断逻辑实现需求:仅RuntimeException及其子类触发重试,排除NullPointerException,同时支持异常原因链遍历,不需要枚举所有非重试异常。
方案1:自定义BinaryExceptionClassifier构造SimpleRetryPolicy(推荐)
直接基于Spring自带的二元异常分类器组合白、黑名单规则,逻辑严谨且配置简洁:
import org.springframework.classify.BinaryExceptionClassifier; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.support.RetryTemplate; import java.util.Collections; import java.util.Set; // 配置重试白名单:仅RuntimeException及其子类 Set<Class<? extends Throwable>> retryableExceptions = Collections.singleton(RuntimeException.class); // 配置重试黑名单:NullPointerException不重试 Set<Class<? extends Throwable>> nonRetryableExceptions = Set.of(NullPointerException.class); // 构造异常分类器,第四个参数传true即开启异常链遍历 BinaryExceptionClassifier classifier = new BinaryExceptionClassifier( retryableExceptions, true, nonRetryableExceptions, true ); // 构造重试策略,最大重试次数按业务需求调整,示例值3次包含首次调用 SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, classifier); RetryTemplate retryTemplate = RetryTemplate.builder() .customPolicy(retryPolicy) // 退避策略、重试监听器等其他配置按需添加即可 .build();
该分类器的判断逻辑优先级:遍历异常链时,只要命中黑名单直接判定不重试;未命中黑名单的前提下,命中白名单才判定为重试,自动排除所有非RuntimeException类型的异常(包括IOException、Error等),不存在漏配问题。
方案2:通过Predicate自定义异常匹配规则
如果希望保留Builder的链式写法,可直接传入自定义判断谓词,不需要手动构造RetryPolicy:
RetryTemplate retryTemplate = RetryTemplate.builder() .maxAttempts(3) .traversingCauses() // 开启后谓词会自动作用于异常链每一层,无需手动递归遍历 .retryOn(e -> { // 先匹配黑名单:NPE直接不重试 if (e instanceof NullPointerException) { return false; } // 再匹配白名单:仅RuntimeException触发重试 return e instanceof RuntimeException; }) // 其他配置按需添加 .build();
之前逐次调用
notRetryOn排除异常的写法属于黑名单兜底逻辑,默认所有异常都会触发重试,需要枚举所有排除项,确实存在覆盖不全的风险,上述两种方案均为白名单优先逻辑,严谨性更高。
内容的提问来源于stack exchange,提问作者greekgeek
相关产品推荐
相关产品推荐

