首页 > 解决方案 > 运行时重新调度@scheduled cron 表达式而不重新启动应用程序

问题描述

我已经使用预定注释来安排从 db 读取 cronexpression 的任务。但是当我们使用 UI 更改 cron 表达式时,它需要重新启动应用程序。当用户从将调用此方法的 UI 更新时,如何注入TaskScheduler和/或任何其他方法来重新安排而不重新启动。以下代码中的任何示例都会很有帮助。ScheduledFutureupdateTestJobSchedule

目前我有: -

@Configuration
public class BasicConfig {

@Autowired
private TestJobSchedulerRepository testJobSchedulerRepository;

@Bean
public String getCronExpressionFromDb(){
    return testJobSchedulerRepository.findByIsActive(1).getCronExpression();
 }
}

@RestController
@EnableScheduling
@RequestMapping("/api")
public class TestJobController {


    @Scheduled(cron="#{getCronExpressionFromDb}")
    public void doTestJob(){
      // does the job
    }

    // This update cron expression when request comes from UI

  @RequestMapping(value = "/update-testjob-schedule_application",
  method = RequestMethod.POST,
  produces = MediaType.APPLICATION_JSON_VALUE)
   public ResponseEntity<String> updateTestJobSchedule(@RequestBody 
   TestJobScheduler testJobScheduler) throws URISyntaxException {

        if(testJobScheduler.getIsActive() == 0){
            testJobScheduler.setIsActive(1);
        } else{
            testJobScheduler.setIsActive(0);
        }
        testJobSchedulerRepository.save(testJobScheduler);
    return new ResponseEntity<>("{\"status\":\"success\"}", HttpStatus.OK);
}

}

标签: javaspringspring-bootquartz-scheduler

解决方案


您最好的选择是使用该TaskScheduler对象。taskScheduler bean 是在您使用@EnableScheduling注释的类时自动创建的@Configuration。此对象可用于即时调度作业。这是您可以使用它执行的操作的快速示例:

@Configuration
@EnableScheduling
public class CronJobConfiguration implements CommandLineRunner {

    @Autowired
    private TestJobSchedulerRepository testJobSchedulerRepository;

    @Autowired
    private TaskScheduler taskScheduler;

    @Override
    public void run(String... strings) {
        String cronExpression = testJobSchedulerRepository.findByIsActive(1).getCronExpression();
        Trigger trigger = new CronTrigger(cronExpression);
        ScheduledFuture scheduledFuture = taskScheduler
                .schedule(() -> {/* the job you want to run*/}, trigger);

        /* Keep the scheduledFuture to be able to cancel the job later Ex : */
        scheduledFuture.cancel(true);
    }
}

您可能需要保留ScheduledFutureschedule 方法返回的对象,以便能够在某个时候取消作业。此外,您还需要有一个使用 的服务,TaskScheduler以便您可以在调用 updateTestJobSchedule 时安排作业。


推荐阅读