Рубрики
Без рубрики

Завершение работы приложения Spring Boot

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

Автор оригинала: baeldung.

1. Обзор

Управление жизненным циклом приложения Spring Boot очень важно для готовой к работе системы. Контейнер Spring обрабатывает создание, инициализацию и уничтожение всех компонентов с помощью ApplicationContext.

Акцент в этой записи делается на фазе разрушения жизненного цикла. Более конкретно, мы рассмотрим различные способы завершения работы приложения Spring Boot.

Чтобы узнать больше о том, как настроить проект с помощью Spring Boot, ознакомьтесь со статьей Spring Boot Starter или просмотрите конфигурацию Spring Boot .

2. Конечная точка завершения работы

По умолчанию в приложении Spring Boot включены все конечные точки, кроме /shutdown ; это, естественно, часть конечных точек Привода .

Вот зависимость Maven для их настройки:


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

И, если мы хотим также настроить поддержку безопасности, нам нужно:


    org.springframework.boot
    spring-boot-starter-security

Наконец, мы включаем конечную точку завершения работы в файле application.properties :

management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true

Обратите внимание, что мы также должны предоставить любые конечные точки привода, которые мы хотим использовать. В приведенном выше примере мы раскрыли все конечные точки привода, которые будут включать конечную точку /shutdown .

Чтобы закрыть приложение Spring Boot, мы просто вызываем метод POST, подобный этому :

curl -X POST localhost:port/actuator/shutdown

В этом вызове порт представляет порт привода.

3. Закройте контекст приложения

Мы также можем вызвать метод close() непосредственно из контекста приложения.

Давайте начнем с примера создания контекста и его закрытия:

ConfigurableApplicationContext ctx = new 
  SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run();
System.out.println("Spring Boot application started");
ctx.getBean(TerminateBean.class);
ctx.close();

Это уничтожает все бобы, освобождает замки, а затем закрывает фабрику бобов . Для проверки завершения работы приложения мы используем стандартный обратный вызов жизненного цикла Spring с аннотацией @PreDestroy :

public class TerminateBean {

    @PreDestroy
    public void onDestroy() throws Exception {
        System.out.println("Spring Container is destroyed!");
    }
}

Мы также должны добавить боб этого типа:

@Configuration
public class ShutdownConfig {

    @Bean
    public TerminateBean getTerminateBean() {
        return new TerminateBean();
    }
}

Вот результат после выполнения этого примера:

Spring Boot application started
Closing [email protected]
DefaultLifecycleProcessor - Stopping beans in phase 0
Unregistering JMX-exposed beans on shutdown
Spring Container is destroyed!

Здесь важно иметь в виду: при закрытии контекста приложения родительский контекст не затрагивается из-за отдельных жизненных циклов .

3.1. Закройте текущий контекст приложения

В приведенном выше примере мы создали контекст дочернего приложения, а затем использовали метод close () , чтобы уничтожить его.

Если мы хотим закрыть текущий контекст, одним из решений является простой вызов конечной точки привода /shutdown .

Однако мы также можем создать вашу собственную конечную точку:

@RestController
public class ShutdownController implements ApplicationContextAware {
    
    private ApplicationContext context;
    
    @PostMapping("/shutdownContext")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }

    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        this.context = ctx;
        
    }
}

Здесь мы добавили контроллер, который реализует интерфейс ApplicationContextAware и переопределяет метод setter для получения текущего контекста приложения. Затем в методе сопоставления мы просто вызываем метод close () .

Затем мы можем вызвать нашу новую конечную точку, чтобы закрыть текущий контекст:

curl -X POST localhost:port/shutdownContext

Конечно, если вы добавите такую конечную точку в реальное приложение, вам также захочется защитить ее.

4. Выйдите из приложения Пружины

Spring Application регистрирует shutdown hook в JVM, чтобы убедиться, что приложение завершает работу надлежащим образом.

Бобы могут реализовать Генератор кода выхода интерфейс для возврата определенного кода ошибки:

ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
  .web(WebApplicationType.NONE).run();

int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
        // return the error code
        return 0;
    }
});

System.exit(exitCode);

Тот же код с применением Java 8 lambdas:

SpringApplication.exit(ctx, () -> 0);

После вызова System.exit(ExitCode) программа завершается с кодом возврата 0 :

Process finished with exit code 0

5. Убейте процесс приложения

Наконец, мы также можем закрыть приложение Spring Boot из-за пределов приложения с помощью скрипта bash. Наш первый шаг для этой опции состоит в том, чтобы контекст приложения записал его PID в файл:

SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class)
  .web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();

Затем создайте файл shutdown.bat со следующим содержимым:

kill $(cat ./bin/shutdown.pid)

Выполнение shutdown.bat извлекает идентификатор процесса из файла shutdown.pid и использует команду kill для завершения загрузочного приложения.

6. Заключение

В этой быстрой записи мы рассмотрели несколько простых методов, которые можно использовать для завершения работы запущенного приложения Spring Boot.

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

Например, .exit() предпочтительнее, когда нам нужно передать код ошибки в другую среду, скажем, JVM для дальнейших действий. Использование Приложения PID дает большую гибкость, так как мы также можем запустить или перезапустить приложение с помощью скрипта bash.

Наконец, /shutdown здесь, чтобы сделать возможным завершение работы приложений извне через HTTP . Для всех остальных случаев .close() будет работать отлично.

Как обычно, полный код этой статьи доступен в проекте GitHub .