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 .