Springの再試行をテストしていますが、recoverが呼び出されていないようです。それを機能させようとしましたが、それは網羅的であるようです。 @Recoverに引数なし、Throwable、Exceptionを渡しました。再試行の依存関係のバージョンを変更し、Spring Bootの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);
}
};
}
}
RestControllerクラス;
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");
}
}
コンソールのスクリーンショット
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>
私はついに答えを得ました。
@Recoverアノテーションが付けられたメソッドを呼び出すには、同じメソッド引数(および例外)と同じ戻り値の型が必要です。
さまざまなタイプの例外引数を使用してテストしました。より具体的な例外タイプがある場合は、メソッドが呼び出されます。このようなメソッドがある場合は、Exception
引数を持つメソッドよりも呼び出されます。ただし、複数のリカバリメソッドがある場合は、より具体的な例外引数を持つメソッドが1つだけ呼び出されます。
@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";
}