[JAVA] Überprüfen Sie das Verhalten von include, exclude und ExhaustedRetryException von Spring Retry

Überblick

--Überprüfen Sie das Verhalten mit dem Beispielprogramm durch Spring Boot + Spring Retry

Liste des Quellcodes des Beispielprogramms

├── pom.xml
└── src
    └── main
        └── java
            └── info
                └── maigo
                    └── lab
                        └── sample
                            └── retry
                                └── exhausted
                                    ├── HogeApplication.java
                                    ├── HogeController.java
                                    ├── HogeException.java
                                    ├── HogeHogeException.java
                                    └── HogeService.java

Betriebsüberprüfungsumgebung

Maven Build-Datei pom.xml

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>

Server erstellen und starten

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)

Quellcode

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();
    }
}

Ausführungsbeispiel

HogeException auslösen und erneut versuchen

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.

Lassen Sie HogeHogeException nicht erneut versuchen

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.

ExhaustedRetryException tritt auf, wenn @Recover eine Ausnahme auslöst, die nicht abgefangen werden kann

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.

Referenzmaterial

Recommended Posts

Überprüfen Sie das Verhalten von include, exclude und ExhaustedRetryException von Spring Retry
[Java] [Spring] Testen Sie das Verhalten des Loggers
Lassen Sie uns das Gefühl von Spring Boot + Swagger 2.0 überprüfen
Überprüfen Sie das Verhalten von Java Intrinsic Locks mit bpftrace
Überprüfen Sie das Verhalten von getOne-, findById- und Abfragemethoden mit Spring Boot + Spring Data JPA
Über das Verhalten von Ruby Hash # ==
[Schienen] Überprüfen Sie den Inhalt des Objekts
Überprüfen Sie die Version von Cent OS
Teil 4: Passen Sie das Verhalten der von Spring Security 5 unterstützten OAuth 2.0-Anmeldung an
Überprüfen Sie den Migrationsstatus von Schienen
Sehen Sie sich das Verhalten von Entitätsaktualisierungen mit Spring Boot + Spring Data JPA an
Filtern Sie das Ergebnis von BindingResult [Spring]
Die Geschichte der Begegnung mit Spring Custom Annotation
Überprüfen Sie den Inhalt der Parameter mit pry
Anmerkung: [Java] Überprüfen Sie den Inhalt des Verzeichnisses
Informationen zur ersten Anzeige von Spring Framework
Überprüfen Sie die Version der Standard-Web-Software.
[Java] Überprüfen Sie die Anzahl der Zeichen
Untersuchen Sie das Verhalten des JPA-Transaktionszeitlimits
Überprüfen Sie die Funktion der Schnittstelle über den Thread
Organisieren Sie die Unterschiede im Verhalten von @NotBlank, @NotEmpty und @NotNull mit Spring Boot + Thymeleaf
Überprüfen Sie die installierte und aktivierte JDK-Version
Über den offiziellen Startleitfaden für Spring Framework
Die Geschichte der Erhöhung der Spring Boot 1.5-Serie auf die 2.1-Serie
Der offizielle Name von Spring MVC ist Spring Web MVC