Java @如果@Retryable返回一个值,则Recover不起作用

Java @如果@Retryable返回一个值,则Recover不起作用,java,spring-retry,retry-logic,Java,Spring Retry,Retry Logic,我正在尝试实现重试逻辑。我的代码按预期工作,直到重试方法的返回类型无效。当我将其更改为字符串时,@Recover停止工作 @Component public class AdapterImpl { int count = 0; @Retryable(include = {NullPointerException.class, IllegalStateException.class}, backoff = @Backoff(delay = 100, maxDelay =

我正在尝试实现重试逻辑。我的代码按预期工作,直到重试方法的返回类型无效。当我将其更改为字符串时,@Recover停止工作

 @Component
  public class AdapterImpl {
      int count = 0;

    @Retryable(include = {NullPointerException.class, IllegalStateException.class}, backoff = @Backoff(delay = 100, maxDelay = 101), maxAttempts = 5)
    public void retry(String foo) {
        System.out.println(foo + " " + count++);
        if (foo.equals("foo")) {
            throw new NullPointerException("foo");
        } else if (foo.equals("bar")) {
            throw new IllegalStateException("bar");
        }
//        return "hi";
    }

    @Recover
    public void connectionException(NullPointerException e) {
        System.out.println("Retry failure NullPointerException");
    }

    @Recover
    public void connectionException(IllegalStateException e) {
        System.out.println("Retry failure IllegalStateException");
    }
}
@Retryable(include = {NullPointerException.class, IllegalStateException.class}, backoff = @Backoff(delay = 100, maxDelay = 101), maxAttempts = 5)
public String retry(String foo) {
    System.out.println(foo + " " + count++);
    if (foo.equals("foo")) {
        throw new NullPointerException("foo");
    } else if (foo.equals("bar")) {
        throw new IllegalStateException("bar");
    }
    return "hi";
}
对于foo和bar,重试逻辑都起作用。日志如下

bar 0
bar 1
bar 2
bar 3
bar 4
Retry failure IllegalStateException
但是当我将retry方法的返回类型更改为String时,@Recover方法停止工作

 @Component
  public class AdapterImpl {
      int count = 0;

    @Retryable(include = {NullPointerException.class, IllegalStateException.class}, backoff = @Backoff(delay = 100, maxDelay = 101), maxAttempts = 5)
    public void retry(String foo) {
        System.out.println(foo + " " + count++);
        if (foo.equals("foo")) {
            throw new NullPointerException("foo");
        } else if (foo.equals("bar")) {
            throw new IllegalStateException("bar");
        }
//        return "hi";
    }

    @Recover
    public void connectionException(NullPointerException e) {
        System.out.println("Retry failure NullPointerException");
    }

    @Recover
    public void connectionException(IllegalStateException e) {
        System.out.println("Retry failure IllegalStateException");
    }
}
@Retryable(include = {NullPointerException.class, IllegalStateException.class}, backoff = @Backoff(delay = 100, maxDelay = 101), maxAttempts = 5)
public String retry(String foo) {
    System.out.println(foo + " " + count++);
    if (foo.equals("foo")) {
        throw new NullPointerException("foo");
    } else if (foo.equals("bar")) {
        throw new IllegalStateException("bar");
    }
    return "hi";
}
日志如下所示

bar 0
bar 1
bar 2
bar 3
bar 4
2020-04-26 23:28:30.800 ERROR 59644 --- [nio-8087-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.IllegalStateException: bar] with root cause

java.lang.IllegalStateException: bar
我的身材,格雷德尔是

   plugins {
    id 'java'
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}

group 'com.demo.web'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.retry:spring-retry'
    compile 'org.springframework:spring-aspects'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

我做错了什么?

使用spring时有某些规则

作为恢复处理程序的方法调用的注释。 合适的恢复处理程序具有Throwable类型的第一个参数或Throwable的子类型,以及与要从中恢复的@Retryable方法相同类型的返回值。 Throwable first参数是可选的,但是只有在没有其他参数匹配时才会调用没有该参数的方法。 后续参数按顺序从失败方法的参数列表中填充。 因此,请确保您具有与上述规则匹配的可恢复方法

 @Recover
public String connectionException(NullPointerException e, String foo) {
    System.out.println("Retry failure NullPointerException");
}

@Recover
public String connectionException(IllegalStateException e, String foo) {
    System.out.println("Retry failure IllegalStateException");
}

使用spring有一定的规则

作为恢复处理程序的方法调用的注释。 合适的恢复处理程序具有Throwable类型的第一个参数或Throwable的子类型,以及与要从中恢复的@Retryable方法相同类型的返回值。 Throwable first参数是可选的,但是只有在没有其他参数匹配时才会调用没有该参数的方法。 后续参数按顺序从失败方法的参数列表中填充。 因此,请确保您具有与上述规则匹配的可恢复方法

 @Recover
public String connectionException(NullPointerException e, String foo) {
    System.out.println("Retry failure NullPointerException");
}

@Recover
public String connectionException(IllegalStateException e, String foo) {
    System.out.println("Retry failure IllegalStateException");
}

您是否已将恢复方法的返回类型更改为字符串?@Retryable中的恢复字段应填写@recover method name?您是否已将恢复方法的返回类型更改为字符串?@Retryable中的恢复字段应填写@recover method name