Le message d'erreur suivant est émis.
Error:(3, 44) java:Organisation du package.springframework.retry.l'annotation n'existe pas
Error:(11, 4) java:Impossible de trouver le symbole
symbole:Classe réessayable
Il semble que Spring Retry n'a pas été installé, vous pouvez donc installer Spring Retry.
Pour Apache Maven, ajoutez ce qui suit à l'élément dependencies de pom.xml.
<!-- 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>
Pour Gradle, ajoutez ce qui suit aux dépendances de build.gradle.
build.gradle
implementation 'org.springframework.retry:spring-retry:1.2.4.RELEASE'
L'erreur suivante se produit.
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 est requis lors de l'exécution de Spring Retry. Si vous utilisez Spring Boot, c'est une bonne idée d'installer Spring Boot AOP Starter.
Pour Apache Maven, ajoutez ce qui suit à l'élément dependencies de pom.xml.
<!-- 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>
Pour Gradle, ajoutez ce qui suit aux dépendances de build.gradle.
build.gradle
runtime('org.springframework.boot:spring-boot-starter-aop')
Pour utiliser Spring Retry, il est nécessaire de spécifier l'annotation @EnableRetry dans la classe d'application, etc. comme suit.
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);
}
}
Les classes non enregistrées dans le conteneur DI ne seront pas retentées. Spécifiez une annotation telle que @Service @Repository @Component dans la classe à réessayer, comme indiqué ci-dessous.
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;
}
}
Spécifiez le type d'exception à réessayer avec l'annotation @Retryable à la méthode avec valeur ou include (la valeur peut être utilisée comme un alias d'inclusion) comme suit. Il est également possible de spécifier le type d'exception qui n'est pas soumis à une nouvelle tentative avec exclusion.
@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.");
}
Les classes qui ne sont pas enregistrées dans le conteneur DI ne seront pas retentées, spécifiez donc l'annotation @Autowired comme indiqué ci-dessous où vous souhaitez les utiliser.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class DemoController {
//À l'objet de la classe où le processus de nouvelle tentative est écrit@Spécifiez Autowired
@Autowired
private MyRetryableService service;
@RequestMapping("/")
public String index() {
return service.hello("hello", "goodbye");
}
}
L'erreur suivante se produit.
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)
La méthode avec l'annotation @Recover doit correspondre à la signature de méthode à réessayer. Plus précisément, le «type de valeur de retour» et le «type d'exception de cible de relance» sont décrits comme des arguments comme indiqué ci-dessous.
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 {
//La valeur de retour est String
//L'exception est 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.");
}
//La valeur de retour est String
//Décrivez RuntimeException, qui est une exception à réessayer, dans l'argument
@Recover
public String recover(RuntimeException e) {
throw e;
}
}
De plus, l'argument de la méthode d'origine ne doit pas nécessairement exister dans la méthode pour laquelle @Recover est spécifié, mais en l'ajoutant, la valeur transmise à la méthode d'origine est transmise en tant qu'argument, de sorte que des informations peuvent être obtenues.
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 {
//La valeur de retour est String
//L'exception est RuntimeException
//Les arguments sont String foo et 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.");
}
//La valeur de retour est String
//Décrivez RuntimeException, qui est une exception à réessayer, dans l'argument
//Ajouter String foo et String bar des arguments de méthode cible de nouvelle tentative après l'argument d'exception
@Recover
public String recover(RuntimeException e, String foo, String bar) {
System.out.println("foo=" + foo);
System.out.println("bar=" + bar);
throw e;
}
}