--Écrire un exemple de programme et vérifier le comportement de Spring Boot + Spring Retry --Spring Retry élimine le besoin d'écrire du code pour déterminer et contrôler les tentatives de traitement
├── build.gradle
├── settings.gradle
└── src
└── main
└── java
└── info
└── maigo
└── lab
└── sample
└── springretry
├── Application.java
├── HogeController.java
├── HogeService.java
├── KotsuException.java
├── PonException.java
├── PonKotsuRepository.java
└── PonKotsuRetryListener.java
--Renvoie un message en JSON en réponse à une requête HTTP. --PonKotsuRepository est un dépôt pompeux. Il renvoie un message avec une certaine probabilité, mais la plupart échouent. --HogeService appellera à nouveau PonKotsuRepository et réessayera si PonKotsuRepository échoue.
build.gradle
Ajoutez implémentation 'org.springframework.retry: spring-retry: 1.2.4.RELEASE' aux dépendances pour utiliser Spring Retry. Ajoutez également runtime'org.springframework.boot: spring-boot-starter-aop 'car il nécessite la classe AOP au moment de l'exécution. Vous trouverez comment spécifier les bibliothèques dépendantes dans GitHub \ -spring \ -projects / spring \ -retry.
plugins {
// The Java Plugin
// https://docs.gradle.org/current/userguide/java_plugin.html
id 'java'
// Gradle - Plugin: org.springframework.boot
// https://plugins.gradle.org/plugin/org.springframework.boot
id 'org.springframework.boot' version '2.2.0.M4'
// Gradle - Plugin: io.spring.dependency-management
/// https://plugins.gradle.org/plugin/io.spring.dependency-management
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
}
group = 'info.maigo.lab'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 11
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:2.2.0.M4'
implementation 'org.springframework.retry:spring-retry:1.2.4.RELEASE'
runtime 'org.springframework.boot:spring-boot-starter-aop'
}
settings.gradle
pluginManagement {
repositories {
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
gradlePluginPortal()
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'org.springframework.boot') {
useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}")
}
}
}
}
rootProject.name = 'sample.springretry'
Générez un fichier JAR avec la tâche de construction dans le plug-in Java de Gradle.
$ gradle build
BUILD SUCCESSFUL in 3s
3 actionable tasks: 3 executed
Exécutez le fichier jar généré avec la commande java. Cela démarrera le serveur Web avec Spring Boot.
$ java -jar build/libs/sample.springretry-0.0.1-SNAPSHOT.jar
Application.java
Classe d'entrée de démarrage par Spring Boot. L'annotation @EnableRetry est spécifiée pour utiliser Spring Retry.
package info.maigo.lab.sample.springretry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
@SpringBootApplication
@EnableRetry
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
HogeController.java
Classe de contrôleur qui reçoit une requête HTTP et renvoie une réponse. Lorsqu'une exception se produit, le résultat du traitement par la méthode avec l'annotation @ExceptionHandler est renvoyé.
package info.maigo.lab.sample.springretry;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HogeController {
@Autowired
private HogeService hogeService;
@RequestMapping("/{message}")
public Map<String, Object> index(@PathVariable("message") String message) {
return hogeService.send(message);
}
@ExceptionHandler(Exception.class)
public Map<String, Object> handleException(HttpServletRequest req, Exception e) {
return new HashMap<String, Object>() {
{
put("handleException", e.getMessage());
}
};
}
}
PonKotsuRepository.java
Une classe Repository sournoise. Soulevez PonException ou KotsuException avec une certaine probabilité.
package info.maigo.lab.sample.springretry;
import java.util.Random;
import org.springframework.stereotype.Repository;
/**
*Un référentiel pompeux.
*/
@Repository
public class PonKotsuRepository {
private static final Random r = new Random(System.currentTimeMillis());
/**
*Espérons qu'il renvoie un message, mais échoue presque.
* @param message
* @message de retour
* @lance PonException PonException
* @jette une exception pour les astuces KotsuException
*/
public String send(String message) {
int i = r.nextInt(5);
if (i < 2) {
System.out.println("PonKotsuRepository: Throws PonException.");
throw new PonException();
} else if (i < 4) {
System.out.println("PonKotsuRepository: Throws KotsuException.");
throw new KotsuException();
} else {
System.out.println("PonKotsuRepository: Returns a message.");
return "1/Message que 3 ne transmet pas: " + message;
}
}
}
HogeService.java
Une classe Service qui utilise une classe Repository sournoise. L'annotation @Retryable est utilisée pour spécifier le nombre de tentatives et le temps d'attente avant les tentatives. La méthode avec l'annotation @Recover est appelée lorsqu'une exception se produit même après avoir essayé le nombre de fois spécifié. Cette méthode prend l'exception qui s'est produite lors de la dernière tentative comme premier argument et prend les arguments de la méthode avec l'annotation @Retryable après le deuxième argument. Cette fois, nous avons préparé deux méthodes qui spécifient l'annotation @Recover. L'un est utilisé lorsqu'une PonException se produit et renvoie le résultat sous forme de chaîne. L'autre est utilisé lorsqu'une KotsuException se produit et lève une RuntimeException. Les informations de l'annotation utilisée dans Spring Retry sont Spring \ -Retry \ -Simple and essential code-free retry processing framework et [org \ .springframework \ .retry \ .annotation \ (Spring Retry 1 \ .2 \ .4 \ .RELEASE API )](https://static.javadoc.io/org.springframework.retry/spring-retry/1.2. 4.RELEASE / index.html? Org / springframework / retry / annotation / package-summary.html) sera utile.
package info.maigo.lab.sample.springretry;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.retry.annotation.Recover;
@Service
public class HogeService {
@Autowired
private PonKotsuRepository repository;
@Retryable(value = {PonException.class, KotsuException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))
public Map<String, Object> send(String message) {
String result = repository.send(message);
return new HashMap<String, Object>() {
{
put("result", result);
}
};
}
@Recover
public Map<String, Object> recoverSend(PonException e, String message) {
System.out.println("recoverSend: PonException");
return new HashMap<String, Object>() {
{
put("error", "La dernière chose qui s'est produite était PonException");
}
};
}
@Recover
public Map<String, Object> recoverSend(KotsuException e, String message) {
System.out.println("recoverSend: KotsuException");
throw new RuntimeException("La dernière chose qui s'est produite était KotsuException");
}
}
PonException.java
Exception Pong. Il hérite simplement de RuntimeException.
package info.maigo.lab.sample.springretry;
public class PonException extends RuntimeException {
}
KotsuException.java
Exception pour les pourboires. Il hérite simplement de RuntimeException.
package info.maigo.lab.sample.springretry;
public class KotsuException extends RuntimeException {
}
PonKotsuRetryListener.java
Une classe qui implémente l'interface RetryListener. Il se compose d'un rappel qui est appelé pendant le processus de nouvelle tentative. Dans cette implémentation, l'état du traitement des nouvelles tentatives est sorti sur la sortie standard.
package info.maigo.lab.sample.springretry;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.listener.RetryListenerSupport;
import org.springframework.stereotype.Component;
@Component
public class PonKotsuRetryListener extends RetryListenerSupport {
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
System.out.println("PonKotsuRetryListener#close: " + getThrowableString(throwable));
super.close(context, callback, throwable);
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
System.out.println("PonKotsuRetryListener#onError: " + getThrowableString(throwable));
super.onError(context, callback, throwable);
}
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
System.out.println("PonKotsuRetryListener#open");
return super.open(context, callback);
}
private static String getThrowableString(Throwable throwable) {
return throwable == null ? "null" : throwable.getClass().getSimpleName();
}
}
JSON est généré lors de l'accès au serveur démarré par curl.
$ curl http://localhost:8080/hello
{"result":"1/Message que 3 ne transmet pas: hello"}
Affichez la sortie standard côté serveur. Le message peut être renvoyé normalement en réessayant après que l'exception Pon s'est produite.
PonKotsuRetryListener#open
PonKotsuRepository: Throws PonException.
PonKotsuRetryListener#onError: PonException
PonKotsuRepository: Returns a message.
PonKotsuRetryListener#close: null
$ curl http://localhost:8080/foo
{"error":"La dernière chose qui s'est produite était PonException"}
Affichez la sortie standard côté serveur. Il se produit dans l'ordre exception Pon → exception Kotsu → exception Pon. Pour la dernière exception Pon, PonKotsuRepository # recoverSend renvoie le résultat.
PonKotsuRetryListener#open
PonKotsuRepository: Throws PonException.
PonKotsuRetryListener#onError: PonException
PonKotsuRepository: Throws KotsuException.
PonKotsuRetryListener#onError: KotsuException
PonKotsuRepository: Throws PonException.
PonKotsuRetryListener#onError: PonException
recoverSend: PonException
PonKotsuRetryListener#close: PonException
$ curl http://localhost:8080/bar
{"handleException":"La dernière chose qui s'est produite était KotsuException"}
Affichez la sortie standard côté serveur. Il se produit dans l'ordre exception Pon → exception Kotsu → exception Kotsu. Pour la dernière exception Kotsu, HogeController # handleException renvoie le résultat.
PonKotsuRetryListener#open
PonKotsuRepository: Throws PonException.
PonKotsuRetryListener#onError: PonException
PonKotsuRepository: Throws KotsuException.
PonKotsuRetryListener#onError: KotsuException
PonKotsuRepository: Throws KotsuException.
PonKotsuRetryListener#onError: KotsuException
recoverSend: KotsuException
PonKotsuRetryListener#close: KotsuException
Recommended Posts