2014-04-08 15 views
54

Jak mogę programowo zamknięcieWiosna Boot aplikacja bez kończące VM?Programowo zamknąć aplikację Wiosna Boot

W innych prac, co jest przeciwieństwem

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

'SpringApplication' ma' static' 'sposób WYPŁYNIĘCIE. Zobacz javadoc. –

+0

Tak, ale do tego potrzebuję odniesienia do ApplicationContext, który SpringApplication nie zapewnia. –

+1

'run' zwraca. –

Odpowiedz

55

Zamknięcie SpringApplication zasadzie oznacza zamknięcie stanowiącego podstawę ApplicationContext. Metoda SpringApplication#run(String...) podaje, że ApplicationContext jako ConfigurableApplicationContext. Możesz wtedy samodzielnie wykonać close(). Na przykład,

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

Alternatywnie, można użyć metody staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...) pomocnika zrobi to za Ciebie. Na przykład:

@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

Pytanie: Do czego przypisujesz ApplicationContext? – lincolnadym

+0

@lincolnadym Do 'ConfigurableApplicationContext'. To jest typ zwracany 'run'. Sprawię, że stanie się to bardziej oczywiste w odpowiedzi. –

23

To działa, nawet drukowane.

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

więc dodanie .close() po run()

Objaśnienie:

public ConfigurableApplicationContext run(String... args)

uruchomić aplikację wiosna, tworzenie i orzeźwiający nowy ApplicationContext. Parametry:

args - argumenty aplikacji (zazwyczaj przekazywane od głównej metody Java )

Powroty: uruchomiony ApplicationContext

a:

void close() Zamknij kontekst aplikacji, zwalniając wszystkie zasoby i blokuje implementację. Obejmuje to zniszczenie wszystkich zbuforowanych fasoli singleton. Uwaga: nie wywołuje zamykania w kontekście nadrzędnym: ; Konteksty nadrzędne mają swój własny, niezależny cykl życia.

Metodę tę można wywołać wiele razy bez efektów ubocznych: Kolejne wywołania zamknięte w już zamkniętym kontekście zostaną zignorowane.

Zasadniczo nie zamyka kontekstu nadrzędnego, dlatego maszyna wirtualna nie przestaje działać.

+1

To działało idealnie z Spring Batch. – cahen

25

W aplikacji rozruchowej sprężyny można użyć coś jak ten

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

W aplikacji można wykorzystać SpringApplication. To ma statyczny exit() metodę, która przyjmuje dwa argumenty: z ApplicationContext oraz ExitCodeGenerator:

czyli można zadeklarować tą metodą:

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

Wewnątrz testy integracyjne można osiągniętych dodając @DirtiesContext adnotacji na poziom klasy:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - Powiązany tekst ApplicationContext zostanie oznaczony jako brudny po zajęciu testu.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - Powiązany kontekst aplikacji zostanie oznaczony jako zabrudzony po każdej metodzie testu w klasie.

tj

@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 { 
... 
Powiązane problemy