Riavvio a livello di codice di un'applicazione Spring Boot

1. Panoramica

In questo tutorial, vi mostreremo come a livello di codice riavviare un'applicazione Primavera di avvio .

Il riavvio della nostra applicazione può essere molto utile in alcuni casi:

  • Ricaricamento dei file di configurazione dopo aver modificato alcuni parametri
  • Modifica del profilo attualmente attivo in fase di esecuzione
  • Reinizializzazione del contesto dell'applicazione per qualsiasi motivo

Sebbene questo articolo copra la funzionalità di riavvio di un'applicazione Spring Boot, tieni presente che abbiamo anche un ottimo tutorial sulla chiusura delle applicazioni Spring Boot.

Ora, esploriamo diversi modi in cui possiamo implementare il riavvio di un'applicazione Spring Boot.

2. Riavvia creando un nuovo contesto

Possiamo riavviare la nostra applicazione chiudendo il contesto dell'applicazione e creando un nuovo contesto da zero. Sebbene questo approccio sia abbastanza semplice, ci sono alcuni dettagli delicati a cui dobbiamo stare attenti per farlo funzionare.

Vediamo come implementarlo nel metodo principale della nostra app Spring Boot:

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

Come possiamo vedere nell'esempio precedente, è importante ricreare il contesto in un thread non daemon separato: in questo modo impediamo che l'arresto della JVM, attivato dal metodo close , chiuda la nostra applicazione. In caso contrario, la nostra applicazione si arresterebbe poiché la JVM non attende che i thread del demone finiscano prima di terminarli.

Inoltre, aggiungiamo un endpoint REST attraverso il quale possiamo attivare il riavvio:

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

Qui, abbiamo aggiunto un controller con un metodo di mappatura che richiama il nostro metodo di riavvio .

Possiamo quindi chiamare il nostro nuovo endpoint per riavviare l'applicazione:

curl -X POST localhost:port/restart

Ovviamente, se aggiungiamo un endpoint come questo in un'applicazione reale, dovremo proteggerlo anche noi.

3. Endpoint di riavvio dell'attuatore

Un altro modo per riavviare la nostra applicazione consiste nell'utilizzare il RestartEndpoint integrato da Spring Boot Actuator.

Innanzitutto, aggiungiamo le dipendenze Maven richieste:

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

Successivamente, dobbiamo abilitare l'endpoint di riavvio integrato nel nostro file application.properties :

management.endpoint.restart.enabled=true

Ora che abbiamo impostato tutto, possiamo inserire Restart Endpoint nel nostro servizio:

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

Nel codice sopra, stiamo usando il bean RestartEndpoint per riavviare la nostra applicazione. Questo è un bel modo per riavviare perché dobbiamo solo chiamare un metodo che fa tutto il lavoro.

Come possiamo vedere, usare RestartEndpoint è un modo semplice per riavviare la nostra applicazione. D'altro canto, questo approccio presenta uno svantaggio perché richiede di aggiungere le librerie menzionate. Se non li stiamo già utilizzando, questo potrebbe essere un sovraccarico eccessivo solo per questa funzionalità. In tal caso, possiamo attenerci all'approccio manuale della sezione precedente poiché richiede solo poche righe di codice in più.

4. Aggiornamento del contesto dell'applicazione

In alcuni casi, possiamo ricaricare il contesto dell'applicazione chiamando il suo metodo di aggiornamento.

Sebbene questo metodo possa sembrare promettente, solo alcuni tipi di contesto dell'applicazione supportano l'aggiornamento di un contesto già inizializzato. Ad esempio, FileSystemXmlApplicationContext , GroovyWebApplicationContext e pochi altri lo supportano.

Sfortunatamente, se lo proviamo in un'applicazione web Spring Boot, otterremo il seguente errore:

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

Infine, sebbene ci siano alcuni tipi di contesto che supportano più aggiornamenti, dovremmo evitare di farlo. Il motivo è che il metodo di aggiornamento è progettato come un metodo interno utilizzato dal framework per inizializzare il contesto dell'applicazione.

5. conclusione

In questo articolo, abbiamo esplorato diversi modi per riavviare un'applicazione Spring Boot a livello di programmazione.

Come sempre, possiamo trovare il codice sorgente per gli esempi su GitHub.