目 录CONTENT

文章目录

Spring Boot 重试机制@Retryable

陌念
2024-12-10 / 0 评论 / 0 点赞 / 8 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

一、解释下 springboot中 @Retryable 注解

@Retryable注解是 Spring Retry 模块提供的一个注解,用于在方法调用失败时自动重试。它可以帮助开发者处理临时性错误,比如网络故障、服务不可用等场景。以下是对 @Retryable 注解的详细解释:

  1. 功能:当方法执行抛出指定异常时,自动重试该方法。
  2. 配置
    • maxAttempts:最大重试次数,默认为 3。
    • backoff:重试之间的等待时间,可以设置延迟策略。
    • includeexclude:指定哪些异常会触发重试。
  3. 用法:通常在服务层的方法上使用,确保在遇到可恢复的异常时,能够自动重试。

伪代码步骤

  1. 导入 Spring Retry 依赖。
  2. 在应用程序中启用 Spring Retry。
  3. 在方法上使用 @Retryable 注解,指定重试参数。
  4. 处理可能的异常。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { CustomException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void myMethod() throws CustomException {
        // 业务逻辑
        // 可能会抛出 CustomException
    }

    @Recover
    public void recover(CustomException e) {
        // 处理最终失败的逻辑
    }
}

二、配合 @Recover 能达到什么效果

@Recover 注解与 @Retryable 注解结合使用时,可以实现更好的异常处理和恢复机制。以下是它的效果和用法:

效果

  1. 异常处理:当 @Retryable 注解的方法在所有重试后仍然失败时,@Recover 注解的方法将被调用,可以在这里处理最终失败的逻辑。
  2. 分离逻辑:通过 @Recover 方法,可以将重试逻辑与失败后的处理逻辑分开,使代码更加清晰和可维护。
  3. 自定义恢复:可以根据不同的异常类型定义不同的恢复方法,提供灵活的错误处理策略。

伪代码步骤

  1. 定义一个带有 @Recover 注解的方法,与 @Retryable 方法在同一类中。
  2. @Recover 方法的参数需与 @Retryable 方法的异常类型一致。
  3. @Recover 方法中实现失败后的处理逻辑。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { CustomException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void myMethod() throws CustomException {
        // 业务逻辑
        // 可能会抛出 CustomException
    }

    @Recover
    public void recover(CustomException e) {
        // 处理最终失败的逻辑,例如记录日志或发送通知
        System.out.println("Method failed after retries: " + e.getMessage());
    }
}

三、能在同一个类中添加多个重试方法吗?

是的,可以在同一个类中添加多个重试方法。每个方法都可以使用 @Retryable 注解,且可以根据需求配置不同的重试策略和异常类型。每个 @Retryable 方法可以有自己的重试逻辑以及对应的 @Recover 方法。

伪代码步骤

  1. 在同一类中定义多个方法,并为每个方法使用 @Retryable 注解。
  2. 为每个重试方法定义对应的 @Recover 方法,以处理不同的异常。
  3. 可以为每个重试方法配置不同的参数,如最大重试次数和延迟时间。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { CustomException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws CustomException {
        // 业务逻辑,可能抛出 CustomException
    }

    @Recover
    public void recoverMethodA(CustomException e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    @Retryable(value = { AnotherException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void methodB() throws AnotherException {
        // 业务逻辑,可能抛出 AnotherException
    }

    @Recover
    public void recoverMethodB(AnotherException e) {
        // 处理 methodB 最终失败的逻辑
        System.out.println("methodB failed after retries: " + e.getMessage());
    }
}

在这个示例中,MyService 类中有两个重试方法 methodAmethodB,它们分别处理不同的异常,并有各自的恢复逻辑。

四、如果一个类中有多个@Retryable 和 @Recover,这俩注解如何对应上

在一个类中有多个 @Retryable@Recover 注解时,它们会通过方法的参数类型和方法名称来对应。具体来说,每个 @Recover 方法的参数类型必须与其对应的 @Retryable 方法抛出的异常类型相匹配。以下是详细说明:

对应规则

  1. 异常类型匹配@Recover 方法的第一个参数必须是与 @Retryable 方法中抛出的异常类型相同的异常类型。
  2. 方法名称:虽然方法名称不是匹配的必要条件,但为了代码可读性,通常建议使用描述性的方法名称,例如 recoverMethodA 对应 methodA
  3. 可选参数@Recover 方法可以有其他参数(如原方法的参数),这使得在恢复逻辑中可以获取到原始方法的输入。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { CustomException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws CustomException {
        // 业务逻辑,可能抛出 CustomException
    }

    @Recover
    public void recoverMethodA(CustomException e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    @Retryable(value = { AnotherException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void methodB() throws AnotherException {
        // 业务逻辑,可能抛出 AnotherException
    }

    @Recover
    public void recoverMethodB(AnotherException e) {
        // 处理 methodB 最终失败的逻辑
        System.out.println("methodB failed after retries: " + e.getMessage());
    }
}

在这个示例中:

  • methodA 抛出 CustomException,对应的恢复方法是 recoverMethodA
  • methodB 抛出 AnotherException,对应的恢复方法是 recoverMethodB

这样通过异常类型和方法名称的匹配,Spring 能够正确地将 @Retryable@Recover 注解对应起来。

五、如果a方法抛出Exception ,b方法抛出 CustomException ,这时候该如何对应

在这种情况下,如果一个方法(a 方法)抛出 Exception,而另一个方法(b 方法)抛出 CustomException,你可以在 b 方法的 @Recover 注解中处理 Exception 类型的异常。这样可以实现更通用的异常处理逻辑。

对应规则

  1. 异常层次结构CustomExceptionException 的子类,因此 @Recover 方法可以接受 Exception
  2. 方法参数:你可以为 @Recover 方法定义一个接受 Exception 的参数,以及其他必要的参数(如原始方法的参数)。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws Exception {
        // 业务逻辑,可能抛出 Exception
        throw new Exception("Error in methodA");
    }

    @Retryable(value = { CustomException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void methodB() throws CustomException {
        // 业务逻辑,可能抛出 CustomException
        throw new CustomException("Error in methodB");
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    @Recover
    public void recoverMethodB(CustomException e) {
        // 处理 methodB 最终失败的逻辑
        System.out.println("methodB failed after retries: " + e.getMessage());
    }
}

关键点

  • methodA 抛出 Exception,对应的恢复方法 recoverMethodA 接受 Exception 类型的参数。
  • methodB 抛出 CustomException,对应的恢复方法 recoverMethodB 接受 CustomException 类型的参数。
  • 如果 methodA 在重试后仍然失败,recoverMethodA 将被调用处理 Exception
  • methodB 的重试逻辑专门处理 CustomException,并在所有重试后调用 recoverMethodB

这样设计使得你可以在一个类中处理多种异常类型,并根据不同的异常提供不同的恢复处理逻辑。

六、按照规则Exception 包含CustomException,像上面的写法a重试方法会捕捉到b方法吗

在 Spring Retry 中,@Retryable 注解的方法不会捕获其他方法的异常。每个 @Retryable 注解的方法都是独立的,它们的重试逻辑只会针对自身抛出的异常进行处理。因此,methodA 重试时不会影响到 methodB,反之亦然。

关键点

  1. 独立性:每个 @Retryable 方法的异常处理是独立的。methodA 的重试逻辑只针对其自身抛出的 Exception,而不会捕获 methodB 抛出的 CustomException
  2. 异常层次:虽然 CustomExceptionException 的子类,但在 @Retryable 的上下文中,methodAmethodB 是分开的。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws Exception {
        // 业务逻辑,可能抛出 Exception
        throw new Exception("Error in methodA");
    }

    @Retryable(value = { CustomException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void methodB() throws CustomException {
        // 业务逻辑,可能抛出 CustomException
        throw new CustomException("Error in methodB");
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    @Recover
    public void recoverMethodB(CustomException e) {
        // 处理 methodB 最终失败的逻辑
        System.out.println("methodB failed after retries: " + e.getMessage());
    }
}

总结

  • methodAmethodB 的重试逻辑是独立的。
  • methodA 抛出的 Exception 不会被 methodB@Retryable 逻辑捕获,反之亦然。
  • 每个方法的 @Recover 逻辑只处理该方法定义的异常类型。

七、如果b方法抛出BusException,这时会被a的重试方法捕捉到吗

在 Spring Retry 中,methodA 的重试逻辑不会捕获 methodB 抛出的 BusException。每个 @Retryable 方法的异常处理是相互独立的。

关键点

  1. 方法独立性:每个 @Retryable 注解的方法都只处理自身抛出的异常。methodA 的重试逻辑只会处理它自己抛出的异常(如 Exception),而不会处理 methodB 抛出的 BusException
  2. 异常传播:如果 methodA 调用了 methodB,并且 methodB 抛出了 BusException,那么 methodA 需要显式处理这个异常(如使用 try-catch 语句),否则该异常将导致 methodA 失败。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws Exception {
        try {
            methodB(); // 调用 methodB
        } catch (BusException e) {
            // 处理 BusException 或者重新抛出
            throw new Exception("Caught BusException from methodB", e);
        }
    }

    @Retryable(value = { BusException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void methodB() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodB");
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    @Recover
    public void recoverMethodB(BusException e) {
        // 处理 methodB 最终失败的逻辑
        System.out.println("methodB failed after retries: " + e.getMessage());
    }
}

总结

  • methodA 不会自动捕获 methodB 抛出的 BusException,除非它显式调用 methodB 并在 try-catch 块中处理该异常。
  • 如果 methodA 捕获并重新抛出 BusException,则可以通过其 @Retryable 注解的配置进行重试。

八、就是说,如果a方法抛出了CustomException 的时候,不会触发重试机制吗

是的,如果 methodA 抛出了 CustomException,并且 methodA@Retryable 注解没有将 CustomException 包含在重试的异常类型列表中,则不会触发重试机制。

关键点

  1. 异常类型匹配@Retryable 注解指定的异常类型决定了哪些异常会触发重试。如果 methodA 抛出的异常不在 @Retryable 注解的 value 属性中,重试机制将不会被触发。
  2. 自定义异常:如果 methodA 抛出 CustomException,而 @Retryable 只配置了重试其他异常(如 Exception),则该异常不会导致重试。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws CustomException {
        // 业务逻辑,可能抛出 CustomException
        throw new CustomException("Error in methodA");
    }

    @Retryable(value = { BusException.class }, maxAttempts = 5, backoff = @Backoff(delay = 2000))
    public void methodB() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodB");
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    @Recover
    public void recoverMethodB(BusException e) {
        // 处理 methodB 最终失败的逻辑
        System.out.println("methodB failed after retries: " + e.getMessage());
    }
}

结论

  • 在上面的示例中,methodA 抛出的 CustomException 不会触发重试,因为 @Retryable 只配置了对 Exception 的重试。
  • 要使 CustomException 触发重试,需要将其添加到 @Retryablevalue 属性中,例如 @Retryable(value = { CustomException.class, Exception.class })。这样,如果 methodA 抛出 CustomException,则会触发重试机制。

九、如果a指定了Exception,但是没有指定CustomException,执行方法中的代码时抛出了CustomException,这时会触发重试机制吗

如果 methodA@Retryable 注解指定了 Exception 作为重试的异常类型,但没有指定 CustomException,那么当 methodA 中的代码抛出 CustomException 时,将不会触发重试机制。

关键点

  1. 重试机制依据@Retryable 注解的 value 属性指定了哪些异常会触发重试。如果抛出的异常不在这个列表中,则重试机制不会被触发。
  2. 异常层次CustomExceptionException 的子类,但在 @Retryable 的上下文中,只有被明确列出的异常才会导致重试。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws Exception {
        // 业务逻辑,可能抛出 CustomException
        throw new CustomException("Error in methodA"); // 这里抛出 CustomException
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }
}

结论

  • 在上面的示例中,如果 methodA 抛出了 CustomException,由于 @Retryable 只指定了 Exception,因此不会触发重试机制。
  • 要使 CustomException 触发重试,必须将其添加到 @Retryablevalue 属性中,例如:
    @Retryable(value = { CustomException.class, Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    
  • 这样配置后,如果 methodA 抛出 CustomException,则会触发重试机制。

十、果a没有指定@Retryable value中的异常,但是在方法加上了throws Exception,这时a抛出BusinessException,会触发重试机制吗?@Recover的方法参数使用了Exception,这时会触发@Recover方法吗?

在这种情况下,如果 methodA 没有在 @Retryablevalue 属性中指定任何异常类型,但方法签名中使用了 throws Exception,则行为如下:

  1. 触发重试机制:如果 methodA 抛出 BusinessException,由于 @Retryable 没有指定任何异常类型,重试机制不会被触发。@Retryable 需要明确指定异常类型,才能对此类异常进行重试。
  2. 调用 @Recover 方法:由于重试机制没有被触发,@Recover 方法也不会被调用。@Recover 方法只有在重试机制成功完成且仍然抛出指定的异常时才会被调用。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    // 没有指定 @Retryable 的 value
    @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws Exception {
        // 业务逻辑,抛出 BusinessException
        throw new BusinessException("Error in methodA");
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }
}

结论

  • 在上述示例中,methodA 抛出的 BusinessException 不会触发重试机制,因为 @Retryable 没有指定要重试的异常类型。
  • 由于没有触发重试,@Recover 方法也不会被调用。

解决方案

如果希望 BusinessException 触发重试,需要在 @Retryable 中指定它,例如:

@Retryable(value = { BusinessException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))

这样配置后,如果 methodA 抛出 BusinessException,则会触发重试机制,并在重试失败后调用 @Recover 方法。

十一、可以我看源码说明,如果不指定,则重试所有异常

在 Spring Retry 的实现中,如果在 @Retryable 注解中没有指定 value 属性,默认情况下会重试所有未被捕获的异常。这是因为 @Retryable 的行为是基于 RetryTemplate 的,而 RetryTemplate 会捕获所有未处理的异常。

源码说明

在 Spring Retry 的源码中,@Retryable 的行为主要由 RetryTemplateRetryPolicy 决定。默认情况下,RetryTemplate 会使用 SimpleRetryPolicy,该策略会重试所有异常。

关键代码

以下是 RetryTemplateSimpleRetryPolicy 中的相关部分的简化示例:

public class RetryTemplate {

    private RetryPolicy retryPolicy;

    public void execute(RetryCallback<T> callback) {
        // 省略其他代码
        while (true) {
            try {
                return callback.doWithRetry(context);
            } catch (Throwable e) {
                if (!retryPolicy.canRetry(context)) {
                    throw e; // 如果不可以重试,则抛出异常
                }
            }
        }
    }
}

public class SimpleRetryPolicy implements RetryPolicy {

    @Override
    public boolean canRetry(RetryContext context) {
        // 如果没有指定异常,则允许重试所有异常
        return true;
    }
}

结论

  • 如果 @Retryable 没有指定 value,则默认会重试所有未捕获的异常。
  • 这意味着在方法中抛出的任何异常(包括 BusinessException)都会触发重试机制。
  • 当重试次数用尽后,@Recover 方法会被调用(如果定义了)。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    // 没有指定 @Retryable 的 value,默认重试所有异常
    @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws Exception {
        // 业务逻辑,抛出 BusinessException
        throw new BusinessException("Error in methodA");
    }

    @Recover
    public void recoverMethodA(Exception e) {
        // 处理 methodA 最终失败的逻辑
        System.out.println("methodA failed after retries: " + e.getMessage());
    }
}

在这个示例中,如果 methodA 抛出 BusinessException,将会触发重试机制,并在重试失败后调用 @Recover 方法。

十二、现在有三个方法value都是指定BusException,这时@Recover该如何对应上

如果你有三个方法,它们的 @Retryable 注解的 value 都指定为 BusException,那么你可以为每个方法定义一个对应的 @Recover 方法。每个 @Recover 方法的参数类型应该与对应的 @Retryable 方法抛出的异常类型一致。

关键点

  1. 对应关系:每个 @Recover 方法需要与特定的 @Retryable 方法相对应。@Recover 方法的参数类型应与 @Retryable 方法中抛出的异常类型一致。
  2. 方法重载:如果需要,你可以根据不同的方法名称来定义不同的 @Recover 方法,或者通过方法签名区分。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { BusException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodA");
    }

    @Retryable(value = { BusException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodB() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodB");
    }

    @Retryable(value = { BusException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodC() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodC");
    }

    // 对应 methodA 的 @Recover 方法
    @Recover
    public void recoverMethodA(BusException e) {
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    // 对应 methodB 的 @Recover 方法
    @Recover
    public void recoverMethodB(BusException e) {
        System.out.println("methodB failed after retries: " + e.getMessage());
    }

    // 对应 methodC 的 @Recover 方法
    @Recover
    public void recoverMethodC(BusException e) {
        System.out.println("methodC failed after retries: " + e.getMessage());
    }
}

结论

  • 在上述示例中,methodAmethodBmethodC 都指定了重试 BusException
  • 每个方法都有一个对应的 @Recover 方法,能够处理其各自的失败情况。
  • 通过这种方式,你可以为不同的方法提供特定的恢复逻辑。

十三、抛出的异常都一致,三个@Recover如何找到对应的@Retryable方法

在 Spring Retry 中,当抛出的异常类型一致时,@Recover 方法的匹配是通过方法的名称来区分的。每个 @Recover 方法的名称应该与其对应的 @Retryable 方法名称相匹配。Spring 会根据 @Recover 方法的名称来确定它对应的 @Retryable 方法。

关键点

  1. 方法命名@Recover 方法的名称必须与其对应的 @Retryable 方法的名称一致,或者通过方法参数的类型来匹配。
  2. 参数类型@Recover 方法的参数类型必须与 @Retryable 方法抛出的异常类型一致。

示例代码

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { BusException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodA() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodA");
    }

    @Retryable(value = { BusException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodB() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodB");
    }

    @Retryable(value = { BusException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public void methodC() throws BusException {
        // 业务逻辑,可能抛出 BusException
        throw new BusException("Error in methodC");
    }

    // 对应 methodA 的 @Recover 方法
    @Recover
    public void recoverMethodA(BusException e) {
        System.out.println("methodA failed after retries: " + e.getMessage());
    }

    // 对应 methodB 的 @Recover 方法
    @Recover
    public void recoverMethodB(BusException e) {
        System.out.println("methodB failed after retries: " + e.getMessage());
    }

    // 对应 methodC 的 @Recover 方法
    @Recover
    public void recoverMethodC(BusException e) {
        System.out.println("methodC failed after retries: " + e.getMessage());
    }
}

结论

  • 在上面的示例中,methodAmethodBmethodC 都重试 BusException
  • 每个方法都有一个 @Recover 方法,名称分别为 recoverMethodArecoverMethodBrecoverMethodC,这样 Spring 就能根据方法名称找到对应的 @Retryable 方法。
  • 通过这种方式,可以确保每个方法的恢复逻辑是相互独立的。
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
  3. QQ打赏

    qrcode qq

评论区