使用 spring 调度程序重新安排任务

pra*_*vat 5 cron spring spring-scheduled

我有一个 spring 调度程序,它有三个具有不同触发器(cron 触发器)的任务。对于这些任务中的每一个,我都有一个可以修改 cron 表达式的 UI。我想在服务收到更新请求时重新安排任务。下面是我的调度程序配置。如何在运行时更改其中一项任务的计划(当 UI 发送更新数据库中的 cron 表达式的请求时)。使用下面的方法,调度器只更新下一个调度。即在调用触发器时调用 nextExecutionTime() 方法。

@Configuration
@EnableScheduling
public class Config implements SchedulingConfigurer {

    @Inject
    MyDao db;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);

        List<TaskConfig> conf = db.readTaks();
        conf.forEach((TaskConfig aTask) -> {
            taskRegistrar.addTriggerTask(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Running task + " + aTask.getName());
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(final TriggerContext triggerContext) {
                    String expression = aTask.getCronExpression();
                    CronTrigger trigger = new CronTrigger(expression);
                    Date nextExec = trigger.nextExecutionTime(triggerContext);
                    return nextExec;
                }
            });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:例如。考虑我的 cron 表达式设置为最初在每小时的第 40 分钟触发,当前时间是上午 11:20。现在,如果我现在更新 cron 以在第 25 分钟触发,我希望任务在上午 11:25 触发。但是对于上面的代码,它在上午 11:40 触发,然后在下午 12:25 触发。这不是我想要的行为。

Abh*_*kar 1

我认为你有两个选择:

  1. 刷新上下文;假设您更新了数据库以便db.readTaks()返回更新的时间表,这将起作用。
  2. 添加新时间的触发器,执行一次。这可以通过注入ScheduledTaskRegistrar并添加上午 11:25 的触发器来完成,如您的示例所示。这是一个粗略的例子:

    @Autowired
    private ScheduledTaskRegistrar taskRegistrar;
    
    void runOnce() {
        taskRegistrar.scheduleCronTask(task);
    }
    
    Run Code Online (Sandbox Code Playgroud)