Перейти к основному содержимому

Программный перезапуск приложения Spring Boot

· 4 мин. чтения

1. Обзор

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

Перезапуск нашего приложения может быть очень удобен в некоторых случаях:

  • Перезагрузка конфигурационных файлов при изменении какого-либо параметра
  • Изменение текущего активного профиля во время выполнения
  • Повторная инициализация контекста приложения по любой причине

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

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

2. Перезапустите, создав новый контекст

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

Давайте посмотрим, как реализовать это в основном методе нашего приложения Spring Boot:

@SpringBootApplication
public class Application {

private static ConfigurableApplicationContext context;

public static void main(String[] args) {
context = SpringApplication.run(Application.class, args);
}

public static void restart() {
ApplicationArguments args = context.getBean(ApplicationArguments.class);

Thread thread = new Thread(() -> {
context.close();
context = SpringApplication.run(Application.class, args.getSourceArgs());
});

thread.setDaemon(false);
thread.start();
}
}

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

Кроме того, давайте добавим конечную точку REST, через которую мы можем инициировать перезапуск:

@RestController
public class RestartController {

@PostMapping("/restart")
public void restart() {
Application.restart();
}
}

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

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

curl -X POST localhost:port/restart

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

3. Конечная точка перезапуска привода

Еще один способ перезапустить наше приложение — использовать встроенную RestartEndpoint из Spring Boot Actuator .

Во-первых, давайте добавим необходимые зависимости Maven:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>

Затем мы должны включить встроенную конечную точку перезапуска в нашем файле application.properties :

management.endpoint.restart.enabled=true

Теперь, когда мы все настроили, мы можем внедрить конечную точку перезапуска в нашу службу: ``

@Service
public class RestartService {

@Autowired
private RestartEndpoint restartEndpoint;

public void restartApp() {
restartEndpoint.restart();
}
}

В приведенном выше коде мы используем bean- компонент RestartEndpoint для перезапуска нашего приложения. Это хороший способ перезапуска, потому что нам нужно вызвать только один метод, который сделает всю работу.

Как мы видим, использование RestartEndpoint — это простой способ перезапустить наше приложение. С другой стороны, у этого подхода есть недостаток, поскольку он требует добавления упомянутых библиотек. Если мы их еще не используем, это может быть слишком много накладных расходов только для этой функциональности. В этом случае мы можем придерживаться ручного подхода из предыдущего раздела, поскольку для этого требуется всего несколько строк кода.

4. Обновление контекста приложения

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

Хотя этот метод может показаться многообещающим, только некоторые типы контекста приложения поддерживают обновление уже инициализированного контекста. Например, FileSystemXmlApplicationContext , GroovyWebApplicationContext и некоторые другие поддерживают его.

К сожалению, если мы попробуем это сделать в веб-приложении Spring Boot, мы получим следующую ошибку:

java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts:
just call 'refresh' once

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

5. Вывод

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

Как всегда, исходный код примеров можно найти на GitHub .