1. Введение
Библиотека Spring Scheduling позволяет приложениям выполнять код через определенные промежутки времени. Поскольку интервалы задаются с помощью аннотации @Scheduled ,
они обычно являются статическими и не могут меняться в течение жизненного цикла приложения .
В этом руководстве мы рассмотрим различные способы условного включения запланированных заданий Spring.
2. Использование логического флага
Самый простой способ условно включить запланированное задание Spring — использовать логическую
переменную , которую мы проверяем внутри запланированного задания. Переменная может быть аннотирована с помощью @Value
, чтобы сделать ее настраиваемой с использованием обычных механизмов конфигурации Spring :
@Configuration
@EnableScheduling
public class ScheduledJobs {
@Value("${jobs.enabled:true}")
private boolean isEnabled;
@Scheduled(fixedDelay = 60000)
public void cleanTempDirectory() {
if(isEnabled) {
// do work here
}
}
}
Недостатком является то, что запланированное задание всегда будет выполняться Spring , что в некоторых случаях может быть не идеальным.
3. Использование @ConditionalOnProperty
Другой вариант — использовать аннотацию @ConditionalOnProperty
. Он принимает имя свойства Spring и запускается, только если свойство имеет значение true.
Во-первых, мы создаем новый класс, который инкапсулирует код запланированного задания, включая интервал расписания:
public class ScheduledJob {
@Scheduled(fixedDelay = 60000)
public void cleanTempDir() {
// do work here
}
}
Затем мы условно создаем bean-компонент этого типа:
@Configuration
@EnableScheduling
public class ScheduledJobs {
@Bean
@ConditionalOnProperty(value = "jobs.enabled", matchIfMissing = true, havingValue = "true")
public ScheduledJob scheduledJob() {
return new ScheduledJob();
}
}
В этом случае задание будет выполняться, если для свойства jobs.enabled
установлено значение true
или если оно вообще отсутствует. Недостатком является то, что эта аннотация доступна только в Spring Boot.
4. Использование профилей Spring
Мы также можем условно включить запланированное задание Spring на основе профиля , с которым работает приложение. Например, этот подход полезен, когда задание должно быть запланировано только в производственной среде.
Этот подход хорошо работает , когда расписание одинаково во всех средах, и его нужно только отключить или включить в определенных профилях .
Это работает аналогично использованию @ConditionalOnProperty
, за исключением того, что мы используем аннотацию @Profile
в нашем методе компонента:
@Profile("prod")
@Bean
public ScheduledJob scheduledJob() {
return new ScheduledJob();
}
Это создаст задание, только если профиль prod
активен . Кроме того, он дает нам полный набор параметров, которые поставляются с аннотацией @Profile
: сопоставление нескольких профилей, сложные выражения spring и многое другое.
При таком подходе нужно быть осторожным с тем, что метод bean-компонента будет выполняться, если профили вообще не указаны .
5. Заполнитель значения в выражении Cron
Используя заполнители значений Spring, мы можем не только условно включить задание, но и изменить его расписание:
@Scheduled(cron = "${jobs.cronSchedule:-}")
public void cleanTempDirectory() {
// do work here
}
В этом примере задание отключено по умолчанию (используя специальное выражение отключения Spring cron).
Если мы хотим включить задание, все, что нам нужно сделать, это предоставить действительное выражение cron для jobs.cronSchedule.
Мы можем сделать это так же, как и любую другую конфигурацию Spring: аргумент командной строки, переменную среды, файл свойств и так далее.
В отличие от выражений cron, здесь нельзя установить фиксированную задержку или значение фиксированной скорости, которые отключают задание. Поэтому этот подход работает только с запланированными заданиями cron .
6. Заключение
В этом руководстве мы увидели несколько различных способов условно включить запланированное задание Spring. Некоторые подходы проще, чем другие, но могут иметь ограничения.
Полный исходный код примеров доступен на GitHub .