Java Spring @Запланированная задача Cron

В настоящее время я сталкиваюсь с проблемой при использовании аннотации @Scheduled (cron) весной.

@Scheduled(cron = "0 0 3 * * MON-FRI", zone = "Europe/Berlin")

Эта задача выполняется каждый день в 3 часа ночи (понедельник-пятница):

  • 03:00:00,278 - 03:00:08,269
  • 03:00:08,269 - 03:00:15,451

Мой вопрос: почему эта задача выполняется дважды? Я заявил, что он должен работать только в минуту «0» и «0» секунд, но это кажется неправильным (см. время выполнения). У меня есть две такие задачи, и у обеих есть эта проблема. Кто-нибудь может знать причину, почему это происходит и как этого избежать?

Я использую версию Spring Boot 2.1.6. Примечание: скоро будет обновление до версии 2.7.

Редактировать:

Мой класс планировщика:

@Component
@RequiredArgsConstructor
@Log4j2
public class LdapTask {

    private final IAppUserService appUserService;
    
    private final IEmployeeService employeeService;
    
    //second, minute, hour, day of month, month, day(s) of week
    @Scheduled(cron = "0 0 3 * * MON-FRI", zone = "Europe/Berlin")
    public void blockAppUsers() {
        /* Logic here */
    }
    
    @Scheduled(cron = "0 20 3 * * MON-FRI")
    public void checkEmailAddresses() {
        /* Logic here */
    }
}

Приложение (запись для этого приложения):

@SpringBootApplication(exclude = MultipartAutoConfiguration.class)
@EntityScan(basePackages = "...")
@EnableScheduling
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
    
    public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
    }
}

Ответ на мою проблему:

Я заменил переопределенный метод configure из SpringBootServletInitializer body на это:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class, LdapTask.class);
}

вместо:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
}

и удаление аннотации @Component в классе LdapTask.

Как намекнул ответ на этот пост, Spring фактически создавал два экземпляра ApplicationContext, которые дважды выполняли этот метод.

Странно, что они бегают один за другим. Вы уверены, что ваш метод не вызывает себя в каком-то случае?

Vladimir Stanciu 18.03.2022 11:42

Да, я проверял несколько раз. Эти два метода «blockAppUsers()» и «checkEmailAddresses» вызываются не мной, а только Spring через аннотацию.

Daniel 18.03.2022 11:58
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Внимательно проверяйте журналы при инициализации приложения.

Скорее всего, ваш планировщик был инициализирован дважды. Одна из причин может быть связана с SpringBootServletInitializer — он может инициализировать bean-компоненты один раз для контекста WebApplicationContext и еще раз для контекста сервлета.

источник

P.S. чтобы дать вам решение, мне понадобится доступ ко всему коду src, так как это может быть даже дополнительная стартовая зависимость в pom

Другие вопросы по теме