Программное завершение работы приложения Spring Boot


Как я могу программно завершение работы a Spring Boot приложение без завершения VM?

в других работах, что является противоположностью

new SpringApplication(Main.class).run(args);
4 62

4 ответа:

закрыть SpringApplication в основном означает закрытие базового ApplicationContext. Элемент SpringApplication#run(String...) метод дает вам, что ApplicationContext как ConfigurableApplicationContext. Вы можете тогда close() это вы сами. Например,

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

кроме того, вы можете использовать staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...) вспомогательный метод, чтобы сделать это для вас. Например,

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

в приложении spring boot вы можете использовать что-то вроде этого

ShutdownManager.java

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

@Component
class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

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

это работает, даже печатается.

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

так что добавление .close() после run()

объяснение:

public ConfigurableApplicationContext run(String... args)

запустите приложение Spring, создав и обновив новый ApplicationContext. Параметры:

args - параметры приложения (как правило, передается из Java-главная метод)

возвращает: a работает ApplicationContext

и:

void close() закройте этот контекст приложения, освободив все ресурсы и блокировки, которые может содержать реализация. Это включает в себя уничтожение все кэшированные одноэлементные бобы. Примечание: не ссылаться на родителей контекст; родительские контексты имеют свой собственный, независимый жизненный цикл.

этот метод может быть вызван несколько раз без побочных эффектов: Последующие закрытые вызовы на уже закрытом контекст будет проигнорирован.

таким образом, в основном, он не будет закрывать Родительский контекст, поэтому виртуальная машина не выходит.

в приложении можно использовать SpringApplication. Это имеет статический exit() метод, который принимает два аргумента:ApplicationContext и ExitCodeGenerator:

т. е. вы можете объявить этот метод:

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

внутри интеграционных тестов вы можете достичь этого, добавив @DirtiesContext аннотации на уровне класса:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - связанный ApplicationContext будет помечен как грязный после теста класс.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - связанный ApplicationContext будет помечен как грязный после каждого метода тестирования в классе.

т. е.

@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 {
...