Luk en Spring Boot-applikation

1. Oversigt

Administration af livscyklussen til Spring Boot Application er meget vigtig for et produktionsklar system. Spring Container håndterer oprettelse, initialisering og destruktion af alle bønner ved hjælp af ApplicationContext.

Vægten af ​​denne opskrivning er ødelæggelsesfasen i livscyklussen. Mere specifikt vil vi se på forskellige måder at lukke en Spring Boot-applikation på.

Hvis du vil vide mere om, hvordan du opretter et projekt ved hjælp af Spring Boot, skal du tjekke Spring Boot Starter-artiklen eller gå gennem Spring Boot Configuration.

2. Lukningens slutpunkt

Som standard er alle slutpunkter aktiveret i Spring Boot Application undtagen /lukke ned; dette er naturligvis en del af Aktuator slutpunkter.

Her er Maven-afhængigheden for at konfigurere disse:

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

Og hvis vi også vil oprette sikkerhedsstøtte, har vi brug for:

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

Endelig aktiverer vi lukningens slutpunkt i application.properties fil:

management.endpoints.web.exposure.include = * management.endpoint.shutdown.enabled = sand endpoints.shutdown.enabled = sand

Bemærk, at vi også skal eksponere eventuelle aktuatorendepunkter, som vi vil bruge. I eksemplet ovenfor har vi eksponeret alle aktuatorendepunkter, som inkluderer /lukke ned slutpunkt.

For at lukke Spring Boot-applikationen kalder vi simpelthen en POST-metode som denne:

curl -X POST localhost: port / aktuator / nedlukning

I dette kald kaldes Havn repræsenterer aktuatorporten.

3. Luk applikationskontekst

Vi kan også ringe til tæt() metode direkte ved hjælp af applikationskonteksten.

Lad os starte med et eksempel på at oprette en kontekst og lukke den:

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

Dette ødelægger alle bønner, frigør låsen og lukker derefter bønnefabrikken. For at bekræfte applikationslukning bruger vi Spring's standard livscyklus-tilbagekald med @PreDestroy kommentar:

offentlig klasse TerminateBean {@PreDestroy offentlig ugyldighed onDestroy () kaster undtagelse {System.out.println ("Spring Container er ødelagt!"); }}

Vi er også nødt til at tilføje en bønne af denne type:

@Configuration public class ShutdownConfig {@Bean public TerminateBean getTerminateBean () {returner ny TerminateBean (); }}

Her er output efter at have kørt dette eksempel:

Spring Boot-applikationen startede Lukning [email protected] DefaultLifecycleProcessor - Stop af bønner i fase 0 Afregistrering af JMX-eksponerede bønner ved lukning Spring Container er ødelagt!

Det vigtige her at huske på: mens lukning af applikationskonteksten påvirkes ikke den overordnede kontekst på grund af separate livscyklusser.

3.1. Luk den aktuelle applikationskontekst

I eksemplet ovenfor oprettede vi en underordnet applikationskontekst og brugte derefter tæt() metode til at ødelægge det.

Hvis vi vil lukke den aktuelle kontekst, er en løsning blot at ringe til aktuatoren /lukke ned slutpunkt.

Vi kan dog også oprette vores eget tilpassede slutpunkt:

@RestController offentlig klasse ShutdownController implementerer ApplicationContextAware {privat ApplicationContext-kontekst; @PostMapping ("/ shutdownContext") offentlig ugyldighed shutdownContext () {((ConfigurableApplicationContext) kontekst) .close (); } @ Override public void setApplicationContext (ApplicationContext ctx) kaster BeansException {this.context = ctx; }}

Her har vi tilføjet en controller, der implementerer ApplicationContextAware interface og tilsidesætter setter-metoden for at opnå den aktuelle applikationskontekst. Derefter kalder vi simpelthen i en kortlægningsmetode tæt() metode.

Vi kan derefter kalde vores nye slutpunkt for at lukke den aktuelle kontekst:

curl -X POST localhost: port / shutdownContext

Selvfølgelig, hvis du tilføjer et slutpunkt som dette i en applikation i det virkelige liv, vil du også gerne sikre det.

4. Afslut SpringApplication

SpringApplication registrerer en lukke ned forbind med JVM for at sikre, at applikationen afsluttes korrekt.

Bønner kan implementere ExitCodeGenerator interface for at returnere en bestemt fejlkode:

ConfigurableApplicationContext ctx = new SpringApplicationBuilder (Application.class) .web (WebApplicationType.NONE) .run (); int exitCode = SpringApplication.exit (ctx, ny ExitCodeGenerator () {@ Override public int getExitCode () {// returner fejlkoden return 0;}}); System.exit (exitCode);

Den samme kode med anvendelsen af ​​Java 8 lambdas:

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

Efter at have ringet til System.exit (exitCode), programmet afsluttes med en 0 returkode:

Processen afsluttet med udgangskode 0

5. Dræb App-processen

Endelig kan vi også lukke en Spring Boot-applikation udefra applikationen ved hjælp af et bash-script. Vores første skridt til denne mulighed er at få applikationskonteksten til at skrive sin PID i en fil:

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

Opret derefter en shutdown.bat fil med følgende indhold:

dræb $ (kat ./bin/shutdown.pid)

Udførelsen af shutdown.bat ekstraherer proces-id'et fra shutdown.pid fil og bruger dræbe kommando for at afslutte Boot-applikationen.

6. Konklusion

I denne hurtige opskrivning har vi dækket nogle få enkle metoder, der kan bruges til at lukke en kørende Spring Boot-applikation.

Mens det er op til udvikleren at vælge en passende metode; alle disse metoder skal bruges af design og med vilje.

For eksempel, .Afslut() foretrækkes, når vi har brug for at videregive en fejlkode til et andet miljø, sig JVM for yderligere handlinger. Ved brug afAnsøgningPID giver mere fleksibilitet, da vi også kan starte eller genstarte applikationen med brug af bash script.

Langt om længe, /lukke neder her for at gøre det muligt at afslutte applikationerne eksternt via HTTP. For alle andre sager .tæt() fungerer perfekt.

Som sædvanlig er den komplette kode til denne artikel tilgængelig på GitHub-projektet.