spring - 获取 @Recover 注释的参数类型不匹配错误

标签 spring spring-annotations spring-retry recover

我有一个具有以下定义的方法

    @Retryable(value = {
            APICallFailedException.class,
            IOException.class}, maxAttempts = TransformerConstants.GET_API_MAX_ATTEMPTS, backoff = @Backoff(delay = TransformerConstants.DELAY))
        public <T> T getAPIResponse(String url, Class<T> classType)

其中 APICallFailedException.class 扩展了运行时异常类

我有一个恢复方法,当所有重试尝试失败时都会调用该方法。它有以下定义

    @Recover
        public <T> T getBackendResponseFallback(RuntimeException exception, String getAPIURL,
            Class<T> classType) 

我通过在末尾添加一个 String 参数来更改这两个方法的方法定义,所以现在它们看起来像

     @Retryable(value = {
               APICallFailedException.class,
               IOException.class}, maxAttempts = TransformerConstants.GET_API_MAX_ATTEMPTS, backoff = @Backoff(delay = TransformerConstants.DELAY))
                public <T> T getAPIResponse(String url, Class<T> classType, **String APIUrl**)
        
    
         @Recover
                public <T> T getBackendResponseFallback(RuntimeException exception, String getAPIURL,
                Class<T> classType, **String apiURL**) 

执行此操作后,当可重试方法失败并调用recover时,会抛出参数不匹配异常

下面是堆栈跟踪

    Caused by: java.lang.IllegalArgumentException: argument type mismatch
               at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
               at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
               at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
               at java.lang.reflect.Method.invoke(Method.java:498)
               at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
               at org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler.recover(RecoverAnnotationRecoveryHandler.java:73)
               at org.springframework.retry.interceptor.RetryOperationsInterceptor$ItemRecovererCallback.recover(RetryOperationsInterceptor.java:141)
               at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:512)
               at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:351)
               at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180)
               at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:115)
               at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:153)
               at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
               at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
               at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
               at com.kroger.cxp.app.transformer.util.RestClientUtil$$EnhancerBySpringCGLIB$$6079045e.getAPIResponse(<generated>)

我想了解为什么会发生这种情况。 Spring doc在@Recover中说最佳匹配方法是根据第一个参数的类型和正在处理的异常的类型来选择的。选择类层次结构中最接近的匹配,因此,例如,如果正在处理 IllegalArgumentException 并且有一个第一个参数是 RuntimeException 的方法,那么它将优先于第一个参数是 Throwable 的方法

getAPIResponse 方法调用其内部的另一个方法并定义

    private HttpResponse<byte[]> callAPI(OkHttpClient okHttpClient, String url, Request request)

是否有可能在 Recover 方法参数中添加字符串参数后,它会尝试与第二个 API 调用匹配,即 callAPI 而不是预期的 getAPIResponse

最佳答案

用你的代码对我来说效果很好;您能提供更多详细信息吗?

@SpringBootApplication
@EnableRetry
public class So68724467Application {

    public static void main(String[] args) {
        SpringApplication.run(So68724467Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(Foo foo) {
        return args -> {
            System.out.println(foo.getAPIResponse("foo", Object.class, "bar"));
        };
    }

}

@Component
class Foo {

    @Retryable(value = {
            IllegalStateException.class,
            IOException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000))
    public <T> T getAPIResponse(String url, Class<T> classType, String APIUrl) {
        System.out.println("Retryable");
        throw new IllegalStateException("test");
    }

    @Recover
    public <T> T getBackendResponseFallback(RuntimeException exception, String getAPIURL,
            Class<T> classType, String apiUR) {

        System.out.println("Recover");
        return (T) new Object();
    }

}

关于spring - 获取 @Recover 注释的参数类型不匹配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68724467/

相关文章:

java - 没有xml的spring+hibernate映射类

java - 使用 Spring Integration 命令总线启动/停止通过注释定义的 AbstractEndpoints

java - 未使用 Spring AMQP StatefulRetryOperationsInterceptor

java - Spring Autowired 组件在 bean 方法中为 null

java - 带有 vaadin spring 应用程序的 tomcat 上出现 NoSuchMethodError

aop - 切入点将所有方法与自定义注释匹配

spring - 预授权错误处理

java - 带有注释的 Spring Retry 框架不起作用

http - 哪些 HTTP 错误不应该触发自动重试?

spring - Docker Kerberos WebHDFS 身份验证异常 : Unauthorized