Spring Retry: метод с аннотацией @Recover не вызывается - PullRequest
0 голосов
/ 14 мая 2018

Я тестирую весеннюю повторную попытку, но кажется, что восстановление не вызывается.Пытался заставить это работать, но это кажется исчерпывающим.Я перешел к @Recover без аргументов, Throwable, Exception.Изменена версия зависимости повторных попыток, и, похоже, она включена в aop для весенней загрузки и удалена.Не удалось получить восстановление, это не вызов со следующим сообщением об исключении:

Ошибка обработки запроса;вложенное исключение: org.springframework.retry.ExhaustedRetryException: не удается найти метод восстановления;Вложенное исключение - java.lang.ArithmeticException: / by zero] с основной причиной

Любая помощь будет высоко ценится

Код, который я выгляжу, выглядит ниже.

Класс конфигурации

package hello;

import java.util.Arrays;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;

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

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {

        System.out.println("Let's inspect the beans provided by `Spring Boot:");`

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}

}

Класс Rest Controller;

package hello;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {

@Autowired
private SomeService service;

@RequestMapping("/")
public String hello() {
    String result = service.getInfo();
    return result;
}

}

Класс обслуживания:

ackage hello;

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 SomeService {

@Retryable(value = ArithmeticException.class, maxAttempts = 3, `backoff = @Backoff(delay = 3000))`
public String getInfo() {
    System.out.println("How many time will this be printed?");
    return "Hello" + 4/0;
}

@Recover
public void helpHere(ArithmeticException cause) {
        System.out.println(cause);
        System.out.println("Recovery place!");
}

Это мой список зависимостей

 <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- tag::actuator[] -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- end::actuator[] -->
    <!-- tag::tests[] -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- end::tests[] -->
    <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
        </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>

С try-catch и различными аргументами

 @Service
public class SomeService {

    @Retryable(value = {ArithmeticException.class}, maxAttempts = 3, `backoff = @Backoff(delay = 3000))`
public String getInfo() {
        try {
        System.out.println("How many time will this be printed?");
        return "Hello" + 4/0;
    } catch(ArithmeticException ex) {
            System.out.println("In the arthemetic Exception");
            throw new ArithmeticException();
    }   
}

@Recover
public void helpHere(ArithmeticException cause) {
        System.out.println(cause);
        System.out.println("Recovery place! ArithmeticException");
}
@Recover
public void helpHere(Exception cause ) {
        System.out.println(cause);
        System.out.println("Recovery place! Exception");
}

@Recover
public void helpHere(Throwable cause) {
        System.out.println(cause);
        System.out.println("Recovery place! Exception");
}

@Recover
public void helpHere() {
        System.out.println("Recovery place! Exception");
}
}

Снимок экрана консоли

enter image description here

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Я наконец получил ответ.

Для вызова метода, аннотированного @Recover, он должен иметь тот же аргумент метода (плюс исключение) и тот же тип возврата.

Я протестировал его с другим типом аргумента исключения, и методы вызываются, если они имеют более конкретный тип исключения. Если у меня есть такой метод, будет вызван метод с аргументом Exception. Однако, если у меня есть несколько методов восстановления, будет вызван только один с более конкретным аргументом исключения.

@Recover
public String helpHere(ArithmeticException cause) {

Финальный код Пример

package hello;

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 SomeService {

@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 3000))
public String getInfo() {
        try {
        System.out.println("How many time will this be printed?");
        return "Hello" + 4/0;
    } catch(Exception ex) {
            System.out.println("In the arthemetic Exception");
            throw new ArithmeticException();
    }   
}

@Recover
public String helpHere(ArithmeticException cause) {

        System.out.println("Recovery place! ArithmeticException");
        return "Hello";
}
@Recover
public String helpHere(Exception cause ) {

        System.out.println("Recovery place! Exception");
        return "Hello";
}

@Recover
public String helpHere() {
        System.out.println("Recovery place! Exception");
        return "Hello";
}

@Recover
public String helpHere(Throwable cause) {

        System.out.println("Recovery place! Throwable");
        return "Hello";
}

введите описание изображения здесь

0 голосов
/ 14 мая 2018

Вы должны использовать try-catch, чтобы справиться с этим. Вот пример

@Retryable(value = ArithmeticException.class, maxAttempts = 5, backoff = @Backoff(delay = 3000))
    public String getInfo() {
        try {
            System.out.println("How many time will this be printed?");
            return "Hello" + 4 / 0;
        } catch (ArithmeticException ex) {
            // will be retried
            throw ex;
        }
    }

throw ex; является обязательным условием, так как он сообщает Spring, что необходимо применить повторную обработку. С @Recover мы определяем отдельный метод восстановления для ArithmeticException. Это позволяет нам запускать специальный код восстановления при сбое повторяющегося метода с ArithmeticException.

Вы можете обратиться к Как обработать повтор с помощью Spring-Retry?

Редактировать

На основании последнего исключения попробуйте предоставить версию для повторного запуска

 <dependency>
       <groupId>org.springframework.retry</groupId>
       <artifactId>spring-retry</artifactId>
       <version>1.2.1.RELEASE</version>
 </dependency>
...