知識庫 / Spring RSS 訂閱

如何觸發和停止計劃中的 Spring Batch 任務

Spring
HongKong
4
01:45 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將研究和比較不同方法以觸發和停止計劃中的 Spring Batch 作業,以滿足任何所需業務用例

如果您需要有關 Spring Batch 和 Scheduler 的介紹,請參閲 Spring-Batch 和 Spring-Scheduler 文章。

2. 觸發計劃中的 Spring Batch 任務

首先,我們有一個名為 SpringBatchScheduler 的類,用於配置調度和批處理任務。 launchJob() 方法將被註冊為計劃任務。

為了以最直觀的方式觸發計劃中的 Spring Batch 任務,我們添加一個條件標誌,僅當標誌設置為 true 時才觸發任務。

private AtomicBoolean enabled = new AtomicBoolean(true);

private AtomicInteger batchRunCounter = new AtomicInteger(0);

@Autowired
private JobLauncher jobLauncher;

@Autowired
private JobRepository jobRepository;

@Autowired
private PlatformTransactionManager transactionManager;

@Scheduled(fixedRate = 2000)
public void launchJob() throws Exception {
    Date date = new Date();
    logger.debug("scheduler starts at " + date);
    if (enabled.get()) {
       JobExecution jobExecution = jobLauncher.run(job(jobRepository, transactionManager), new JobParametersBuilder().addDate("launchDate", date)
                  .toJobParameters());
       batchRunCounter.incrementAndGet();
       logger.debug("Batch job ends with status as " + jobExecution.getStatus());
    }
    logger.debug("scheduler ends ");
}

變量 batchRunCounter 將在集成測試中使用,以驗證批次作業是否已停止。

3. 停止計劃中的 Spring Batch 任務

通過上述條件標誌,我們可以觸發計劃中的 Spring Batch 任務,即使任務處於活動狀態。

如果不需要恢復任務,我們可以實際停止計劃任務以節省資源。

在下一節中,我們將探討兩種選擇。

3.1. 使用調度器後處理器

由於我們使用 @Scheduled 註解來調度一個方法,因此調度器後處理器 ScheduledAnnotationBeanPostProcessor 應該首先被註冊。

我們可以顯式地調用 postProcessBeforeDestruction() 方法來銷燬指定的調度Bean:

@Test
public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception {
    ScheduledAnnotationBeanPostProcessor bean = context
      .getBean(ScheduledAnnotationBeanPostProcessor.class);
    SpringBatchScheduler schedulerBean = context
      .getBean(SpringBatchScheduler.class);
    await().untilAsserted(() -> Assert.assertEquals(
      2, 
      schedulerBean.getBatchRunCounter().get()));
    bean.postProcessBeforeDestruction(
      schedulerBean, "SpringBatchScheduler");
    await().atLeast(3, SECONDS);

    Assert.assertEquals(
      2, 
      schedulerBean.getBatchRunCounter().get());
}

考慮到多個調度器,最好將每個調度器放在自己的類中,這樣我們就可以根據需要停止特定的調度器。

3.2. 取消計劃任務 未來任務

手動取消調度器的一種方式是取消其 未來任務

以下是一個自定義任務調度器,用於捕獲 未來任務 映射:

@Bean
public TaskScheduler poolScheduler() {
    return new CustomTaskScheduler();
}

private class CustomTaskScheduler 
  extends ThreadPoolTaskScheduler {

    //

    @Override
    public ScheduledFuture<?> scheduleAtFixedRate(
      Runnable task, long period) {
        ScheduledFuture<?> future = super
          .scheduleAtFixedRate(task, period);

        ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task;
        scheduledTasks.put(runnable.getTarget(), future);

        return future;
    }
}

然後,我們迭代 Future 地圖,並取消對我們的批次作業調度器的 Future

public void cancelFutureSchedulerTasks() {
    scheduledTasks.forEach((k, v) -> {
        if (k instanceof SpringBatchScheduler) {
            v.cancel(false);
        }
    });
}

在具有多個調度器任務的情況下,我們可以維護自定義調度器池中的 Future 映射,並根據調度器類取消相應的已調度 Future

4. 結論

在本文中,我們嘗試了三種不同的方法來觸發或停止 Spring Batch 任務。

當需要重啓批處理任務時,使用條件標誌來管理任務運行狀態將是一種靈活的解決方案。 否則,我們可以遵循其他兩種選項來完全停止調度器。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.