--Überprüfen Sie das Verhalten mit dem Beispielprogramm durch Spring Boot + Spring Retry
├── pom.xml
└── src
└── main
└── java
└── info
└── maigo
└── lab
└── sample
└── retry
└── exhausted
├── HogeApplication.java
├── HogeController.java
├── HogeException.java
├── HogeHogeException.java
└── HogeService.java
Führen Sie diesmal den Build mit Maven aus. pom.xml basiert auf der von Spring Initializr generierten. Fügen Sie den Abhängigkeiten Spring-Retry hinzu, um Spring Retry zu verwenden. Fügen Sie außerdem Spring-Boot-Starter-AOP hinzu, da die AOP-Klasse zur Laufzeit erforderlich ist.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.M4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>info.maigo.lab</groupId>
<artifactId>sample.retry.exhausted</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sample.retry.exhausted</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 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>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
Generieren Sie eine JAR-Datei mit dem Befehl mvn package.
$ mvn package
Starten Sie den Server, indem Sie die JAR-Datei mit dem Befehl java angeben.
$ java -jar target/sample.retry.exhausted-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.0.M4)
HogeApplication.java
Boot-Einstiegsklasse von Spring Boot. Die Annotation @EnableRetry ist für die Verwendung von Spring Retry angegeben.
package info.maigo.lab.sample.retry.exhausted;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
@SpringBootApplication
@EnableRetry
public class HogeApplication {
public static void main(String[] args) {
SpringApplication.run(HogeApplication.class, args);
}
}
HogeController.java
Controller-Klasse, die eine HTTP-Anforderung empfängt und eine Antwort zurückgibt. Wenn eine Ausnahme auftritt, behandeln Sie sie mit der Methode, die die Annotation @ExceptionHandler angibt.
package info.maigo.lab.sample.retry.exhausted;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HogeController {
@Autowired
private HogeService hogeService;
@RequestMapping("/")
public Map<String, Object> index(@RequestParam(name = "name", defaultValue = "java.lang.RuntimeException") String name) throws Exception {
return new HashMap<String, Object>() {
{
put("result", hogeService.invoke(name));
}
};
}
@ExceptionHandler(Exception.class)
public Map<String, Object> handleException(HttpServletRequest req, Exception e) {
return new HashMap<String, Object>() {
{
put("handleException", e.getClass().getName() + " / " + e.getMessage());
}
};
}
}
HogeException.java
Eine Ausnahmeklasse, die nur von Exception erbt.
package info.maigo.lab.sample.retry.exhausted;
public class HogeException extends Exception {
}
HogeHogeException.java
Eine Ausnahmeklasse, die von HogeException erbt.
package info.maigo.lab.sample.retry.exhausted;
public class HogeHogeException extends HogeException {
}
HogeService.java
Serviceklasse. Die Methode invoke erstellt ein Ausnahmeobjekt basierend auf der angegebenen Zeichenfolge und löst es aus. Die Annotation @Retryable wird in der Aufrufmethode angegeben. Include gibt den Ausnahmetyp an, der wiederholt werden soll, und exclude gibt den Ausnahmetyp an, der nicht wiederholt werden soll. Geben Sie die Anzahl der Wiederholungen mit maxAttempts an. Geben Sie die Wartezeit bis zum erneuten Versuch mit Backoff an. Die Methode mit der Annotation @Recover wird aufgerufen, wenn eine Ausnahme auch nach dem angegebenen Versuch auftritt (auch wenn die Ausnahme nicht das Ziel eines erneuten Versuchs ist, wird diese Methode aufgerufen, wenn sie dem Typ entspricht).
package info.maigo.lab.sample.retry.exhausted;
import java.lang.reflect.Constructor;
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 {
@Retryable(
include = {HogeException.class},
exclude = {HogeHogeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String invoke(String name) throws Exception {
System.out.println("HogeService#invoke: " + name);
Class cls = Class.forName(name);
Constructor cnst = cls.getDeclaredConstructor();
Exception e = (Exception) cnst.newInstance();
throw e;
}
@Recover
public String recover(HogeException e, String name) {
System.out.println("HogeService#recover: " + name);
return "HogeService#recover: " + e.getClass().getName();
}
}
Wenn Sie mit Curl auf den gestarteten Server zugreifen, wird JSON ausgegeben. Gibt an, dass eine HogeException auftreten soll. Die Wiederherstellungsmethode gibt eine Zeichenfolgendarstellung von HogeException zurück.
$ curl http://localhost:8080/?name=info.maigo.lab.sample.retry.exhausted.HogeException
{"result":"HogeService#recover: info.maigo.lab.sample.retry.exhausted.HogeException"}
Zeigen Sie das Standardausgabeprotokoll auf der Serverseite an. Sie können sehen, dass die Wiederherstellungsmethode aufgerufen wird, nachdem der Wiederholungsversuch ausgeführt wurde, und die Aufrufmethode dreimal aufgerufen wird.
HogeService#invoke: info.maigo.lab.sample.retry.exhausted.HogeException
HogeService#invoke: info.maigo.lab.sample.retry.exhausted.HogeException
HogeService#invoke: info.maigo.lab.sample.retry.exhausted.HogeException
HogeService#recover: info.maigo.lab.sample.retry.exhausted.HogeException
Da HogeException in include of @Retryable annotation angegeben ist, wird die Wiederholungsverarbeitung ausgeführt. Wenn bei der letzten Wiederholung eine Ausnahme auftritt, wird die Methode mit der Annotation @Recover aufgerufen.
Zugriff mit Curl durch Angabe, dass eine HogeHogeException auftritt. Die Wiederherstellungsmethode gibt eine Zeichenfolgendarstellung von HogeHogeException zurück.
$ curl http://localhost:8080/?name=info.maigo.lab.sample.retry.exhausted.HogeHogeException
{"result":"HogeService#recover: info.maigo.lab.sample.retry.exhausted.HogeHogeException"}
Zeigen Sie das Standardausgabeprotokoll auf der Serverseite an. Sie können sehen, dass die Wiederherstellungsmethode aufgerufen wird, nachdem die Aufrufmethode nur einmal aufgerufen wurde.
HogeService#invoke: info.maigo.lab.sample.retry.exhausted.HogeHogeException
HogeService#recover: info.maigo.lab.sample.retry.exhausted.HogeHogeException
HogeHogeException wird unter Ausschluss der Annotation @Retryable angegeben, sodass keine Wiederholungsverarbeitung durchgeführt wird. Ich habe die Aufrufmethode einmal aufgerufen und eine HogeHogeException erhalten, und die Wiederherstellungsmethode wurde aufgerufen und die resultierende Zeichenfolge zurückgegeben. Außerdem ist HogeHogeException eine Unterklasse von HogeException, die in include von @Retryable-Annotation angegeben ist. Wenn also HogeHogeException nicht in exclude angegeben ist, wird sie wiederholt.
Zugriff mit Curl durch Angabe, dass java.lang.Exception auftritt. Eine org.springframework.retry.ExhaustedRetryException-Ausnahme wird ausgelöst, ohne von der Wiederherstellungsmethode abgefangen zu werden.
$ curl http://localhost:8080/?name=java.lang.Exception
{"handleException":"org.springframework.retry.ExhaustedRetryException / Cannot locate recovery method; nested exception is java.lang.Exception"}
Zeigen Sie das Standardausgabeprotokoll auf der Serverseite an. Sie können sehen, dass die Aufrufmethode nur einmal aufgerufen wird. Die Wiederherstellungsmethode wurde nicht aufgerufen.
HogeService#invoke: java.lang.Exception
Da java.lang.Exception in include of @Retryable annotation nicht angegeben ist, wird keine Wiederholungsverarbeitung durchgeführt. Außerdem wird ExhaustedRetryException ausgelöst, da die Annotation @Recover nicht der Ausnahmetyp ist, der von der angegebenen Methode abgefangen werden kann. In diesem Fall kann die getCause-Methode der ExhaustedRetryException-Klasse verwendet werden, um das Objekt der Ausnahme java.lang.Exception abzurufen, die sie verursacht hat.
Recommended Posts