Programmgesteuerter Neustart einer Spring-Boot-Anwendung

Programmgesteuertes Neustarten einer Spring Boot-Anwendung

1. Überblick

In diesem Tutorial zeigen wir, wie manprogrammatically restart a Spring Boot application macht.

Das Neustarten unserer Anwendung kann in einigen Fällen sehr praktisch sein:

  • Neuladen der Konfigurationsdateien nach Änderung eines Parameters

  • Ändern des aktuell aktiven Profils zur Laufzeit

  • Neuinitialisierung des Anwendungskontexts aus irgendeinem Grund

Während dieser Artikel die Funktionalität des Neustarts einer Spring Boot-Anwendung behandelt, beachten Sie, dass wir auch ein großartiges Tutorial zushutting down Spring Boot applications haben.

Lassen Sie uns nun verschiedene Möglichkeiten untersuchen, wie wir den Neustart einer Spring Boot-Anwendung implementieren können.

2. Starten Sie neu, indem Sie einen neuen Kontext erstellen

Wir können unsere Anwendung neu starten, indem wir den Anwendungskontext schließen und einen neuen Kontext von Grund auf neu erstellen. Obwohl dieser Ansatz recht einfach ist, gibt es einige heikle Details, mit denen wir vorsichtig sein müssen, damit er funktioniert.

Lassen Sie uns sehen, wie dies in dermain-Methode unserer Spring Boot-App implementiert wird:

@SpringBootApplication
public class Application {

    private static ConfigurableApplicationContext context;

    public static void main(String[] args) {
        context = SpringApplication.run(Application.class, args);
    }

    public static void restart() {
        ApplicationArguments args = context.getBean(ApplicationArguments.class);

        Thread thread = new Thread(() -> {
            context.close();
            context = SpringApplication.run(Application.class, args.getSourceArgs());
        });

        thread.setDaemon(false);
        thread.start();
    }
}

Wie wir im obigen Beispiel sehen können, ist es wichtig, den Kontext in einem separaten Nicht-Daemon-Thread neu zu erstellen. Auf diese Weise verhindern wir, dass das durch dieclose-Methode ausgelöste Herunterfahren der JVM unsere Anwendung schließt. Andernfalls wird unsere Anwendung gestoppt, da die JVM nicht auf das Beenden von Daemon-Threads wartet, bevor sie beendet wird.

Fügen wir außerdem einen REST-Endpunkt hinzu, über den wir den Neustart auslösen können:

@RestController
public class RestartController {

    @PostMapping("/restart")
    public void restart() {
        Application.restart();
    }
}

Hier haben wir einen Controller mit einer Zuordnungsmethode hinzugefügt, die unsererestart-Methode aufruft.

Wir können dann unseren neuen Endpunkt aufrufen, um die Anwendung neu zu starten:

curl -X POST localhost:port/restart

Wenn wir einen Endpunkt wie diesen in einer realen Anwendung hinzufügen, müssen wir ihn natürlich auch sichern.

3. Neustart-Endpunkt des Stellantriebs

Eine andere Möglichkeit, unsere Anwendung neu zu starten, besteht darin, die integriertenRestartEndpoint vonSpring Boot Actuator. zu verwenden

Fügen wir zunächst die erforderlichen Maven-Abhängigkeiten hinzu:


    org.springframework.boot
    spring-boot-starter-actuator


    org.springframework.boot
    spring-cloud-starter

Als Nächstes müssen wir den integrierten Neustartendpunkt in unsererapplication.properties-Datei aktivieren:

management.endpoint.restart.enabled=true

Nachdem wir alles eingerichtet haben, können wirRestartEndpoint in unseren Service einspeisen:

@Service
public class RestartService {

    @Autowired
    private RestartEndpoint restartEndpoint;

    public void restartApp() {
        restartEndpoint.restart();
    }
}

Im obigen Code verwenden wir dieRestartEndpoint bean, um unsere Anwendung neu zu starten. Dies ist eine gute Möglichkeit zum Neustart, da nur eine Methode aufgerufen werden muss, die die gesamte Arbeit erledigt.

Wie wir sehen können, ist die Verwendung vonRestartEndpoint eine einfache Möglichkeit, unsere Anwendung neu zu starten. Auf der anderen Seite weist dieser Ansatz einen Nachteil auf, da wir die genannten Bibliotheken hinzufügen müssen. Wenn wir sie noch nicht verwenden, ist dies möglicherweise zu viel Aufwand für nur diese Funktionalität. In diesem Fall können wir uns an die manuelle Vorgehensweise aus dem vorherigen Abschnitt halten, da nur noch wenige Codezeilen erforderlich sind.

4. Aktualisieren des Anwendungskontexts

In einigen Fällen können wir den Anwendungskontext neu laden, indem wir dierefresh-Methode aufrufen.

Obwohl diese Methode vielversprechend klingt, unterstützen nur einige Anwendungskontexttypen die Aktualisierung eines bereits initialisierten Kontexts. Zum Beispiel unterstützenFileSystemXmlApplicationContext,GroovyWebApplicationContext, und einige andere dies.

Wenn wir dies in einer Spring Boot-Webanwendung versuchen, wird leider die folgende Fehlermeldung angezeigt:

java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts:
just call 'refresh' once

Schließlich sollten wir dies vermeiden, obwohl es einige Kontexttypen gibt, die mehrere Aktualisierungen unterstützen. Der Grund dafür ist, dass dierefresh-Methode als interne Methode konzipiert ist, die vom Framework zum Initialisieren des Anwendungskontexts verwendet wird.

5. Fazit

In diesem Artikel haben wir verschiedene Methoden zum programmgesteuerten Neustarten einer Spring Boot-Anwendung untersucht.

Wie immer finden wir den Quellcode für die Beispiele überGitHub.