--Listen Sie die Gegenmaßnahmen für verschiedene Probleme auf, die bei Spring Retry auftreten --Diese Umgebung: Java 8 + Spring Boot 2.2.0 + Spring Retry 1.2.4
Die folgende Fehlermeldung wird ausgegeben.
Error:(3, 44) java:Paket org.springframework.retry.Anmerkung existiert nicht
Error:(11, 4) java:Symbol kann nicht gefunden werden
Symbol:Klasse wiederholbar
Es scheint, dass Spring Retry nicht installiert wurde, sodass Sie Spring Retry installieren können.
Fügen Sie für Apache Maven Folgendes zum Abhängigkeitselement von pom.xml hinzu.
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
Fügen Sie für Gradle Folgendes zu den Abhängigkeiten von build.gradle hinzu.
build.gradle
implementation 'org.springframework.retry:spring-retry:1.2.4.RELEASE'
Der folgende Fehler tritt auf.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Pointcut
AspectJ aspectjweaver ist erforderlich, wenn Spring Retry ausgeführt wird. Wenn Sie Spring Boot verwenden, empfiehlt es sich, Spring Boot AOP Starter zu installieren.
Fügen Sie für Apache Maven Folgendes zum Abhängigkeitselement von pom.xml hinzu.
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>runtime</scope>
</dependency>
Fügen Sie für Gradle Folgendes zu den Abhängigkeiten von build.gradle hinzu.
build.gradle
runtime('org.springframework.boot:spring-boot-starter-aop')
Um Spring Retry verwenden zu können, muss die Annotation @EnableRetry in der Anwendungsklasse usw. wie folgt angegeben werden.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
@SpringBootApplication
@EnableRetry
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Klassen, die nicht im DI-Container registriert sind, werden nicht wiederholt. Geben Sie eine Anmerkung wie @Service @Repository @Component in der Klasse an, die wie unten gezeigt wiederholt werden soll.
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 DemoService {
@Retryable(
value = {RuntimeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String hello(String foo, String bar) {
throw new RuntimeException("This is a sample error.");
}
@Recover
public String recover(RuntimeException e, String foo, String bar) {
throw e;
}
}
Geben Sie den Ausnahmetyp an, der mit der Annotation @Retryable für die Methode mit Wert oder Include (Wert kann als Alias für Include verwendet werden) wie folgt wiederholt werden soll. Es ist auch möglich, den Ausnahmetyp anzugeben, für den kein erneuter Versuch mit Ausschluss erforderlich ist.
@Retryable(
include = {Exception.class},
exclude = {RuntimeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String hello(String foo, String bar) {
throw new RuntimeException("This is a sample error.");
}
@Retryable(
value = {Exception.class},
exclude = {RuntimeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String hello(String foo, String bar) {
throw new RuntimeException("This is a sample error.");
}
Klassen, die nicht im DI-Container registriert sind, werden nicht wiederholt. Geben Sie daher die Annotation @Autowired wie unten gezeigt an, wo Sie sie verwenden möchten.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class DemoController {
//Zu dem Objekt der Klasse, in das der Wiederholungsprozess geschrieben wird@Geben Sie Autowired an
@Autowired
private MyRetryableService service;
@RequestMapping("/")
public String index() {
return service.hello("hello", "goodbye");
}
}
Der folgende Fehler tritt auf.
org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.RuntimeException: This is a sample error.
at org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler.recover(RecoverAnnotationRecoveryHandler.java:61)
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)
Die Methode mit der Annotation @Recover muss mit der Methodensignatur übereinstimmen, die wiederholt werden soll. Insbesondere werden der "Rückgabewerttyp" und der "Wiederholungszielausnahmetyp" als Argumente beschrieben, wie unten gezeigt.
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 DemoService {
//Der Rückgabewert ist String
//Die Ausnahme ist RuntimeException
@Retryable(
value = {RuntimeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String hello(String foo, String bar) {
System.out.println("DemoService#hello");
throw new RuntimeException("This is a sample error.");
}
//Der Rückgabewert ist String
//Beschreiben Sie im Argument die RuntimeException, eine Ausnahme, die wiederholt werden muss
@Recover
public String recover(RuntimeException e) {
throw e;
}
}
Außerdem muss das Argument der ursprünglichen Methode nicht in der Methode vorhanden sein, für die @Recover angegeben ist. Durch Hinzufügen wird jedoch der an die ursprüngliche Methode übergebene Wert als Argument übergeben, sodass Informationen abgerufen werden können.
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 DemoService {
//Der Rückgabewert ist String
//Die Ausnahme ist RuntimeException
//Argumente sind String foo und String bar
@Retryable(
value = {RuntimeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String hello(String foo, String bar) {
System.out.println("DemoService#hello");
throw new RuntimeException("This is a sample error.");
}
//Der Rückgabewert ist String
//Beschreiben Sie im Argument die RuntimeException, eine Ausnahme, die wiederholt werden muss
//Fügen Sie nach dem Ausnahmeargument den String String foo und den String bar der Argumente der Wiederholungszielmethode hinzu
@Recover
public String recover(RuntimeException e, String foo, String bar) {
System.out.println("foo=" + foo);
System.out.println("bar=" + bar);
throw e;
}
}