2014-04-08 14 views
54

come posso programmazione arresto un Primavera avvio applicazione senza terminare la VM?programmazione spegnere applicazione Primavera Boot

In altre opere, ciò è l'opposto del

new SpringApplication(Main.class).run(args); 
+1

'SpringApplication' ha un' 'metodo exit' static'. Vedi il javadoc. –

+0

Sì, ma per quello ho bisogno di un riferimento a ApplicationContext, che SpringApplication non fornisce. –

+1

'run' lo restituisce. –

risposta

55

chiusura di un SpringApplication sostanzialmente significa chiudere il sottostante ApplicationContext. Il metodo SpringApplication#run(String...) fornisce quello ApplicationContext come ConfigurableApplicationContext. Puoi quindi farlo da solo a close(). Ad esempio,

@SpringBootApplication 
public class Example { 
    public static void main(String[] args) { 
     ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args); 
     // ...determine it's time to shut down... 
     ctx.close(); 
    } 
} 

In alternativa, è possibile utilizzare il metodo staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...) di supporto per farlo per voi. Ad esempio,

@SpringBootApplication 
public class Example { 
    public static void main(String[] args) { 
     ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args); 
     // ...determine it's time to stop... 
     int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() { 
      @Override 
      public int getExitCode() { 
       // no errors 
       return 0; 
      } 
     }); 
     System.exit(exitCode); 
    } 
} 
+0

Domanda: A che cosa si applica ApplicationContext? – lincolnadym

+0

@lincolnadym A 'ConfigurableApplicationContext'. Questo è il tipo di ritorno di 'run'. Lo renderò più ovvio nella risposta. –

23

Questo funziona, anche fatto è stampato.

SpringApplication.run(MyApplication.class, args).close(); 
    System.out.println("done"); 

Così aggiungendo .close() dopo run()

Spiegazione:

public ConfigurableApplicationContext run(String... args)

Eseguire l'applicazione primavera, la creazione e l'aggiornamento di una nuova ApplicationContext. Parametri:

args - gli argomenti di applicazione (di solito passati da un metodo main Java)

Ritorni: un ApplicationContext esecuzione

e:

void close() Chiudi questo contesto applicativo, rilasciando tutte le risorse e blocca che l'implementazione potrebbe contenere. Ciò include la distruzione di tutti i bean singleton memorizzati nella cache. Nota: non richiama chiudi su un contesto genitore ; i contesti genitoriali hanno il loro ciclo di vita indipendente.

Questo metodo può essere chiamato più volte senza effetti collaterali: Le chiamate chiuse successive su un contesto già chiuso verranno ignorate.

Fondamentalmente, non chiuderà il contesto genitore, ecco perché la VM non esce.

+1

Questo ha funzionato perfettamente con Spring Batch. – cahen

25

In un'applicazione di avvio di primavera si può usare qualcosa di simile

ShutdownManager.java

import org.springframework.context.ApplicationContext; 
import org.springframework.boot.SpringApplication; 

class ShutdownManager{ 

    @Autowired 
    private ApplicationContext appContext; 

    public void initiateShutdown(int returnCode){ 
     SpringApplication.exit(appContext,() -> returnCode); 
    } 
} 
1

Nell'applicazione è possibile utilizzare SpringApplication. Questo ha un exit() metodo statico che prende due argomenti: il ApplicationContext e un ExitCodeGenerator:

cioè è possibile dichiarare questo metodo:

@Autowired 
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) { 
    SpringApplication.exit(applicationContext, exitCodeGenerator); 
} 

All'interno i test di integrazione puoi ottenuti con l'aggiunta di @DirtiesContext annotazione a livello di classe:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - Il relativo ApplicationContext verrà contrassegnato come dirty dopo la classe di test.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - Il relativo ApplicationContext verrà contrassegnato come dirty dopo ogni metodo di test nella classe.

cioè

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes = {Application.class}, 
    webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port:0"}) 
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS) 
public class ApplicationIT { 
... 
Problemi correlati