You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将方法传入函数式接口以实现通用重试功能?

实现带重试的JPA Repository方法调用工具

1. 定义泛型函数式接口

针对JPA中findById、findByNumber这类单入参、泛型返回的查询方法,先定义通用函数式接口适配:

@FunctionalInterface
public interface RepositoryQueryFunction<T, R> {
    R execute(T param);
}

其中T为入参类型(如String、Integer),R为返回实体类型(如Employee、Record)。

2. 创建带重试的执行工具类

借助@Retryable实现数据库连接失败时的重试逻辑,工具类统一处理查询方法的执行:

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;

@Component
public class RepositoryRetryHandler {

    // 捕获数据库访问异常,最多重试3次,每次间隔1秒
    @Retryable(
            value = {org.springframework.dao.DataAccessException.class},
            maxAttempts = 3,
            backoff = @Backoff(delay = 1000)
    )
    public <T, R> R executeWithRetry(RepositoryQueryFunction<T, R> queryFunction, T param) {
        return queryFunction.execute(param);
    }
}
  • value指定触发重试的异常范围,DataAccessException覆盖绝大多数数据库相关异常
  • maxAttempts设置最大重试次数
  • backoff配置重试间隔时间

3. 业务代码中使用示例

注入RepositoryRetryHandler,用方法引用直接传入JPA查询方法,替代直接调用:

@Service
public class BusinessService {
    private final EmployeeRepository employeeRepository;
    private final RecordRepository recordRepository;
    private final RepositoryRetryHandler retryHandler;

    // 构造函数注入依赖
    public BusinessService(EmployeeRepository employeeRepository,
                          RecordRepository recordRepository,
                          RepositoryRetryHandler retryHandler) {
        this.employeeRepository = employeeRepository;
        this.recordRepository = recordRepository;
        this.retryHandler = retryHandler;
    }

    public Employee getEmployeeById(String id) {
        // 替代直接调用employeeRepository.findById(id)
        return retryHandler.executeWithRetry(employeeRepository::findById, id)
                .orElseThrow(() -> new RuntimeException("Employee not found"));
    }

    public Record getRecordByNumber(Integer number) {
        // 替代直接调用recordRepository.findByNumber(number)
        return retryHandler.executeWithRetry(recordRepository::findByNumber, number);
    }
}

4. 依赖与启动配置

确保项目引入Spring Retry相关依赖(以Maven为例):

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>

并在启动类添加@EnableRetry开启重试功能:

import org.springframework.retry.annotation.EnableRetry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableRetry
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

内容的提问来源于stack exchange,提问作者Wes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:06:04