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

使用spring调度程序重新调度任务,spring,cron,spring-scheduled,Spring,Cron,Spring Scheduled,我有一个spring调度程序,它有三个具有不同触发器的任务(cron触发器)。对于每个任务,我都有一个可以修改cron表达式的UI。我想在服务收到更新请求时重新安排任务。下面是我的调度程序配置。如何在运行时更改其中一个任务的计划(当UI发送更新数据库中cron表达式的请求时)。使用下面的方法,调度程序仅使用下一个调度更新。i、 e.调用触发器时调用nextExecutionTime()方法 @Configuration @EnableScheduling public class Config

我有一个spring调度程序,它有三个具有不同触发器的任务(cron触发器)。对于每个任务,我都有一个可以修改cron表达式的UI。我想在服务收到更新请求时重新安排任务。下面是我的调度程序配置。如何在运行时更改其中一个任务的计划(当UI发送更新数据库中cron表达式的请求时)。使用下面的方法,调度程序仅使用下一个调度更新。i、 e.调用触发器时调用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;
                }
            });
        });
    }
}
@配置
@使能调度
公共类配置实现SchedulingConfigurer{
@注入
MyDao数据库;
@凌驾
公共无效配置任务(ScheduledTaskRegistrar任务注册器){
ThreadPoolTaskScheduler taskScheduler=新的ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
List conf=db.readTaks();
conf.forEach((TaskConfig-aTask)->{
taskRegistrar.addTriggerTask(新的Runnable(){
@凌驾
公开募捐{
System.out.println(“运行任务+”+aTask.getName());
}
},新触发器(){
@凌驾
公共日期下一个执行时间(最终触发器上下文触发器上下文){
字符串表达式=aTask.getCronExpression();
CronTrigger=新的CronTrigger(表达式);
Date nextExec=触发器.nextExecutionTime(triggerContext);
返回nextExec;
}
});
});
}
}

编辑:例如,考虑我的CRON表达式被设置为在每小时第四十分钟开始触发,当前时间是上午11:20。现在,如果我现在更新cron,使其在25分钟触发,我希望任务在上午11:25触发。但是上面的代码会在上午11:40触发,然后在下午12:25触发。这不是我想要的行为。

我认为您有两种选择:

  • 刷新上下文;假设您更新了数据库,以便
    db.readTaks()
    返回更新的日程安排,那么这将起作用
  • 添加一个新时间的触发器,执行一次。这可以通过注入
    ScheduledTaskRegistrar
    并添加11:25am的触发器来实现,就像您的示例中那样。下面是一个粗略的例子:

    @Autowired
    private ScheduledTaskRegistrar taskRegistrar;
    
    void runOnce() {
        taskRegistrar.scheduleCronTask(task);
    }
    

  • 可能重复的Nope。我在这里也做过类似的事情。但问题是只有在调用nextExecution时间时才会更新触发器。将用一个例子更新问题。你对此有正确的解决方案吗?选项1:你是指应用程序上下文吗?那太可怕了。是否有方法仅刷新计划程序??选择2:我喜欢这个主意。它将在25分钟触发。但是现有的调度程序仍然会在更新自身之前的第50分钟触发任务。是吗?@pravat 1。普通的春豆不能做到这一点;看见2.是的,在这种情况下,您并没有中断现有的计划,只是添加了一个新的临时作业。