java - 运行时重新安排 @scheduled cron 表达式,无需重新启动应用程序

标签 java spring spring-boot quartz-scheduler

我已经使用计划注释来计划从数据库读取 cronexpression 的任务。但是当我们使用 UI 更改 cron 表达式时,需要重新启动应用程序。当用户从 UI 更新时,将调用此方法 updateTestJobSchedule ,如何注入(inject) TaskSchedulerScheduledFuture 或任何其他方法来重新安排而不重新启动。以下代码中的任何示例都会非常有帮助。

目前我有:-

@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);
}

}

最佳答案

最好的选择是使用 TaskScheduler 对象。当您在使用 @Configuration 注释的类上使用 @EnableScheduling 时,会自动创建 taskScheduler bean。该对象可用于动态安排作业。这是您可以用它做什么的快速示例:

@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);
    }
}

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

关于java - 运行时重新安排 @scheduled cron 表达式,无需重新启动应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52152206/

相关文章:

java - 一个模型有多个自定义 DTO

java - org.hibernate.ObjectNotFoundException :No row with the given identifier exists

heroku - 无法为 Spring Boot 应用程序解析 Heroku 上的类

java - spring框架的yml配置文件

spring - 无法使用 Gradle 在 Spring Boot 闭包中设置 Layout = ZIP

java - 字符串 [= 新字符串 vs = ""]

java - 我将图像从一个目录复制到另一个目录,但它打开时显示为灰屏

closures - 在 JDK 1.8 中引入闭包 - Project Lambda

java - 如何继承log4j配置xml?

java - Spring Boot Async ResultSet 已关闭