添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1 问题说明

spring-retry中的@Recover注解,可在重试失败后会执行注解所在方法中的处理逻辑。如何将传递给@Retryable方法的参数传递给@Recover所标注的方法?

2 解决方式

官方文档中指出,恢复方法的参数可以可选地包括抛出的异常和(可选)传递给原始可重试方法的参数。示例:

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public void service(String str1, String str2) {
        // ... do something
    @Recover
    public void recover(RemoteAccessException e, String str1, String str2) {
       // ... error handling making use of original args if required

要解决可以选择进行恢复的多个方法之间的冲突,可以显式指定恢复方法名称。示例:

@Service
class Service {
    @Retryable(recover = "service1Recover", value = RemoteAccessException.class)
    public void service1(String str1, String str2) {
        // ... do something
    @Retryable(recover = "service2Recover", value = RemoteAccessException.class)
    public void service2(String str1, String str2) {
        // ... do something
    @Recover
    public void service1Recover(RemoteAccessException e, String str1, String str2) {
        // ... error handling making use of original args if required
    @Recover
    public void service2Recover(RemoteAccessException e, String str1, String str2) {
        // ... error handling making use of original args if required

1.3.2 及更高版本支持匹配参数化(通用)返回类型以检测正确的恢复方法:

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public List<Thing1> service1(String str1, String str2) {
        // ... do something
    @Retryable(RemoteAccessException.class)
    public List<Thing2> service2(String str1, String str2) {
        // ... do something
    @Recover
    public List<Thing1> recover1(RemoteAccessException e, String str1, String str2) {
       // ... error handling for service1
    @Recover
    public List<Thing2> recover2(RemoteAccessException e, String str1, String str2) {
       // ... error handling for service2

3 测试验证

测试代码:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
 * <pre>
 * 测试@Recover获取参数信息
 * </pre>
 * @author LOOPY_Y
 * @since 2022/4/14
@Service
@Slf4j
public class RecoverGetParamService {
    @Retryable(value = Exception.class, backoff = @Backoff(delay = 5000, multiplier = 2, maxDelay = 8000))
    public Boolean retryMethod(RetryParam retryParam) throws Exception {
        log.info("=================== 进入到retryMethod方法 =====================");
        String name = retryParam.getName();
        if (StringUtils.isBlank(name) || !"小明".equals(name)) {
            log.error("retryMethod准备抛出异常");
            throw new Exception("retryMethod执行时发生异常");
        log.info("name为:{} , age为:{}", name, retryParam.getAge());
        return true;
    @Recover
    public Boolean retryMethodRecover(Exception e, RetryParam retryParam) {
        log.info("=================== 进入到retryMethodRecover方法 =====================");
        log.info("retryParam参数值为:{}", retryParam);
        log.error("异常信息为:", e);
        return false;

测试结果:如图,可以看到参数信息在Recover中已拿到。
在这里插入图片描述

Spring-Retry重试实现原理 Spring实现了一套重试机制,功能简单实用。Spring Retry是从Spring Batch独立出来的一个功能,已经广泛应用于Spring Batch,Spring Integration, Spring for Apache Hadoop等Spring项目。本文将讲述如何使用Spring Retry及其实现原理。 重试,其实我们其实很多时候都需要的,为了保证容错性,可用性,一致性等。一般用来应对外部系统的一些不可预料的返回、异常等,特别是网络延迟,中
在 Controller 里提供接口,通常需要捕捉异常,进行异常处理。最简单的方法使用try/catch进行异常捕捉。 当方法很多,每个都需要 try catch,代码会显得臃肿,写起来也比较麻烦。 这时就需要进行统一的异常处理。 1.使用方法 通过 Spring 的 AOP 特性就可以很方便的实现异常的统一处理:使用@ControllerAdvice、@RestControllerAdvice捕获运行时异常。 新建异常枚举类 package com.local.dev.root.devr
@Retryable 和 @Recover 使用的时候 注意事项 @Recover的注解的方法第一个参数需要是 @Retryable 所捕获的重试异常类型;必须是第一个参数 @Recover注解的方法的 返回值必须 和 @Retryable注解的方法返回值一致 上面两条的原因见文章末尾 最近在使用@Retryable 注解时出现的问题 是 使用了 @Retryable 注解之后;指定了特定的异常进行异常重试机制;设置最大重试次数,当时只设置了@Retryable 注解;但是并没有配合使用 @R
前几天我 Review 代码的时候发现项目里面有一坨逻辑写的非常的不好,一眼望去简直就是丑陋之极。 我都不知道为什么会有这样的代码存在项目里面,于是我看了一眼提交记录准备叫对应的同事问问,为什么会写出这样的代码。 然后... 那一坨代码是我 2019 年的时候提交的。 我细细的思考了一下,当时好像由于对项目不熟悉,然后其他的项目里面又有一个类似的功能,我就直接 CV 大法搞过来了,里面的逻辑也没细看。 嗯,原来是历史原因,可以理解,可以理解。 代码里面主要就是一大坨重试
最近研究了一下spring-retry框架地使用。 spring-retry再1.3.0版中@Retryable增加recover属性,从而使得再异常重试失败后可以指定补偿方法执行。 从而使得我们不需要每一个用到@Recover的地方都需要新建一个类。
如何传递启动参数 Bootloader和Recovery模块以及主系统之间的通信是通过系统的misc分区来完成的。Misc分区只有3页(Page)大小。描述misc分区的数据结构是bootloader_message,定义如下: struct bootloader_message {      char command[32];      char status[32];      
npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: vue-typescript-admin-template@1.0.0 npm ERR! Found: eslint@6.8.0 npm ERR! node_modules/eslint npm ERR! dev eslint@">= 1.6.0 < 7.0.0" from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer eslint@"^7.12.1" from @vue/eslint-config-standard@6.1.0 npm ERR! node_modules/@vue/eslint-config-standard npm ERR! dev @vue/eslint-config-standard@"^6.0.0" from the root project npm ERR! npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. npm ERR! npm ERR! See D:\prj\web\NodeJs\node-v14.17.6-win-x64\node-cache\eresolve-report.txt for a full report. npm ERR! A complete log of this run can be found in: npm ERR! D:\prj\web\NodeJs\node-v14.17.6-win-x64\node-cache\_logs\2023-07-18T09_26_51_696Z-debug-0.log Waiting for the debugger to disconnect...
这个错误是由于依赖冲突导致的。具体来说,你的项目需要 `@vue/eslint-config-standard@^6.0.0`,它依赖于 `eslint@^7.12.1`。然而,你的项目中已经安装了 `eslint@6.8.0`,版本低于 `7.12.1`,造成了冲突。 解决这个问题的方法有几种: 1. 更新 `eslint` 至符合要求的版本。你可以使用以下命令更新 `eslint`: npm install eslint@^7.12.1 2. 如果你确定 `eslint@6.8.0` 可以兼容 `@vue/eslint-config-standard@6.1.0`,可以使用 `--force` 参数忽略错误,强制安装依赖: npm install --force 3. 如果你使用的是 npm 7 或以上版本,可以尝试使用 `--legacy-peer-deps` 参数来解决依赖冲突: npm install --legacy-peer-deps 你可以根据自己的情况选择合适的解决方法。如果问题仍然存在,请提供完整的错误日志以便进一步分析。