Программно отключить Spring Загрузка приложения

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

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

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

Ответ 1

Закрытие 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 time to shut down...
        ctx.close();
    }
}

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

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

Ответ 2

В приложении весенней загрузки вы можете использовать что-то вроде этого

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

Ответ 3

Это работает, даже сделано напечатано.

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

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

Объяснение:

public ConfigurableApplicationContext run(String... args)

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

args - аргументы приложения (обычно передаются из основного метода Java)

Возвращает: работающий ApplicationContext

а также:

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

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

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

Ответ 4

В приложении вы можете использовать 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 {
...

Ответ 5

Это обеспечит правильное закрытие приложения SpringBoot и освобождение ресурсов для операционной системы.

@Autowired
private ApplicationContext context;

@GetMapping("/shutdown-app")
public void shutdownApp() {

    int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
    System.exit(exitCode);
}