Programmgesteuertes Neustarten einer Spring Boot-Anwendung

1. Übersicht

In diesem Tutorial zeigen wir Ihnen, wie Sie eine Spring Boot-Anwendung programmgesteuert neu starten .

Ein Neustart unserer Anwendung kann in einigen Fällen sehr praktisch sein:

  • Neuladen von Konfigurationsdateien beim Ändern einiger Parameter
  • Ändern des aktuell aktiven Profils zur Laufzeit
  • Initialisierung 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 zum Herunterfahren von Spring Boot-Anwendungen 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.

Mal sehen, wie dies in der Hauptmethode 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 die close- Methode ausgelöste Herunterfahren der JVM unsere Anwendung schließt. Andernfalls wird unsere Anwendung gestoppt, da die JVM nicht darauf wartet, dass Daemon-Threads beendet werden, bevor sie beendet werden.

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 unsere Neustartmethode 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. Neustartendpunkt des Stellantriebs

Eine andere Möglichkeit, unsere Anwendung neu zu starten, besteht darin, den integrierten RestartEndpoint von Spring 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 unserer Datei application.properties aktivieren :

management.endpoint.restart.enabled=true

Nachdem wir alles eingerichtet haben, können wir den Restart Endpoint in unseren Service einbinden :

@Service public class RestartService { @Autowired private RestartEndpoint restartEndpoint; public void restartApp() { restartEndpoint.restart(); } }

Im obigen Code verwenden wir die RestartEndpoint- Bean, um unsere Anwendung neu zu starten. Dies ist eine gute Möglichkeit zum Neustart, da wir nur eine Methode aufrufen müssen, die die gesamte Arbeit erledigt.

Wie wir sehen können, ist die Verwendung des RestartEndpoint eine einfache Möglichkeit, unsere Anwendung neu zu starten. Auf der anderen Seite hat dieser Ansatz einen Nachteil, 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 den manuellen Ansatz 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 seine Aktualisierungsmethode aufrufen.

Obwohl diese Methode vielversprechend klingt, unterstützen nur einige Anwendungskontexttypen das Aktualisieren eines bereits initialisierten Kontexts. Beispielsweise unterstützen FileSystemXmlApplicationContext , GroovyWebApplicationContext und einige andere dies.

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

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

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

5. Schlussfolgerung

In diesem Artikel haben wir verschiedene Möglichkeiten untersucht, wie eine Spring Boot-Anwendung programmgesteuert neu gestartet werden kann.

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