Sluit een Spring Boot-applicatie af

1. Overzicht

Het beheren van de levenscyclus van Spring Boot Application is erg belangrijk voor een productieklaar systeem. De Spring-container zorgt voor het maken, initialiseren en vernietigen van alle Beans met behulp van de ApplicationContext.

De nadruk van dit artikel is de vernietigingsfase van de levenscyclus. Meer specifiek zullen we verschillende manieren bekijken om een ​​Spring Boot-applicatie af te sluiten.

Voor meer informatie over het opzetten van een project met Spring Boot, bekijk het Spring Boot Starter-artikel of bekijk de Spring Boot-configuratie.

2. Eindpunt afsluiten

Standaard zijn alle eindpunten ingeschakeld in Spring Boot Application, behalve /afsluiten; dit is natuurlijk onderdeel van de Actuator eindpunten.

Hier is de Maven-afhankelijkheid om deze in te stellen:

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

En als we ook beveiligingsondersteuning willen opzetten, hebben we het volgende nodig:

 org.springframework.boot spring-boot-starter-security 

Ten slotte schakelen we het afsluitingseindpunt in application.properties het dossier:

management.endpoints.web.exposure.include = * management.endpoint.shutdown.enabled = waar endpoints.shutdown.enabled = true

Merk op dat we ook alle actuator-eindpunten moeten blootleggen die we willen gebruiken. In het bovenstaande voorbeeld hebben we alle actuator-eindpunten blootgelegd, waaronder de /afsluiten eindpunt.

Om de Spring Boot-applicatie af te sluiten, noemen we eenvoudig een POST-methode zoals deze:

curl -X POST localhost: poort / actuator / shutdown

In deze oproep is de haven vertegenwoordigt de actuatorpoort.

3. Sluit de toepassingscontext

We kunnen ook bellen met de dichtbij() methode rechtstreeks met behulp van de toepassingscontext.

Laten we beginnen met een voorbeeld van het maken van een context en deze sluiten:

ConfigurableApplicationContext ctx = nieuwe SpringApplicationBuilder (Application.class) .web (WebApplicationType.NONE) .run (); System.out.println ("Spring Boot-applicatie gestart"); ctx.getBean (TerminateBean.class); ctx.close ();

Hierdoor worden alle bonen vernietigd, worden de vergrendelingen vrijgegeven en wordt de bonenfabriek gesloten. Om het afsluiten van de applicatie te verifiëren, gebruiken we de standaard lifecycle callback van Spring met @PreDestroy annotatie:

public class TerminateBean {@PreDestroy public void onDestroy () gooit uitzondering {System.out.println ("Spring Container is vernietigd!"); }}

We moeten ook een boon van dit type toevoegen:

@Configuration openbare klasse ShutdownConfig {@Bean openbare TerminateBean getTerminateBean () {retourneer nieuwe TerminateBean (); }}

Dit is de uitvoer na het uitvoeren van dit voorbeeld:

Spring Boot-applicatie gestart Sluiten [e-mail beveiligd] DefaultLifecycleProcessor - Beans stoppen in fase 0 Registratie van aan JMX blootgestelde bonen ongedaan maken bij afsluiten Spring Container is vernietigd!

Het belangrijkste hier om in gedachten te houden: bij het sluiten van de toepassingscontext wordt de bovenliggende context niet beïnvloed door afzonderlijke levenscycli.

3.1. Sluit de huidige toepassingscontext

In het bovenstaande voorbeeld hebben we een onderliggende toepassingscontext gemaakt en vervolgens de dichtbij() methode om het te vernietigen.

Als we de huidige context willen sluiten, is een oplossing om gewoon de actuator te bellen /afsluiten eindpunt.

We kunnen echter ook ons ​​eigen aangepaste eindpunt maken:

@RestController openbare klasse ShutdownController implementeert ApplicationContextAware {privé ApplicationContext-context; @PostMapping ("/ shutdownContext") public void shutdownContext () {((ConfigurableApplicationContext) context) .close (); } @Override public void setApplicationContext (ApplicationContext ctx) gooit BeansException {this.context = ctx; }}

Hier hebben we een controller toegevoegd die het ApplicationContextAware interface en overschrijft de setter-methode om de huidige toepassingscontext te verkrijgen. Vervolgens noemen we in een mappingmethode eenvoudig de dichtbij() methode.

We kunnen dan ons nieuwe eindpunt aanroepen om de huidige context af te sluiten:

curl -X POST localhost: port / shutdownContext

Als u een dergelijk eindpunt toevoegt aan een real-life applicatie, wilt u dit natuurlijk ook beveiligen.

4. Afsluiten SpringApplication

SpringApplication registreert een afsluiten haak met de JVM om ervoor te zorgen dat de toepassing correct wordt afgesloten.

Bonen kunnen de ExitCodeGenerator interface om een ​​specifieke foutcode te retourneren:

ConfigurableApplicationContext ctx = nieuwe SpringApplicationBuilder (Application.class) .web (WebApplicationType.NONE) .run (); int exitCode = SpringApplication.exit (ctx, nieuwe ExitCodeGenerator () {@Override public int getExitCode () {// retourneer de foutcode return 0;}}); System.exit (exitCode);

Dezelfde code met de toepassing van Java 8 lambdas:

SpringApplication.exit (ctx, () -> 0);

Nadat u het System.exit (exitCode), eindigt het programma met een 0-retourcode:

Proces voltooid met afsluitcode 0

5. Stop het app-proces

Ten slotte kunnen we ook een Spring Boot-applicatie van buiten de applicatie afsluiten door een bash-script te gebruiken. Onze eerste stap voor deze optie is om de toepassingscontext de PID in een bestand te laten schrijven:

SpringApplicationBuilder-app = nieuwe SpringApplicationBuilder (Application.class) .web (WebApplicationType.NONE); app.build (). addListeners (nieuwe ApplicationPidFileWriter ("./ bin / shutdown.pid")); app.run ();

Maak vervolgens een shutdown.bat bestand met de volgende inhoud:

dood $ (cat ./bin/shutdown.pid)

De uitvoering van shutdown.bat haalt de proces-ID uit het shutdown.pid bestand en gebruikt het doden commando om de Boot-applicatie te beëindigen.

6. Conclusie

In dit korte artikel hebben we enkele eenvoudige methoden behandeld die kunnen worden gebruikt om een ​​actieve Spring Boot-applicatie af te sluiten.

Hoewel het aan de ontwikkelaar is om een ​​geschikte methode te kiezen; al deze methoden moeten met opzet en met opzet worden gebruikt.

Bijvoorbeeld, .Uitgang() heeft de voorkeur wanneer we een foutcode moeten doorgeven aan een andere omgeving, bijvoorbeeld JVM voor verdere acties. Gebruik makend vanToepassingPID geeft meer flexibiliteit, omdat we de applicatie ook kunnen starten of herstarten met het gebruik van bash-script.

Tenslotte, /afsluitenis hier om het mogelijk te maken beëindig de applicaties extern via HTTP. Voor alle andere gevallen .dichtbij() zal perfect werken.

Zoals gewoonlijk is de volledige code voor dit artikel beschikbaar op het GitHub-project.