Spring 更新调度程序

标签 spring spring-boot scheduler spring-scheduled

我在 Spring 有一个预定的工作,我从我的数据库中获取它的 cron。
每次执行时,都会更新下一次执行时间。因此,如果将其配置为每 10 分钟运行一次,我可以将值更改到数据库中以每 15 分钟安排一次该作业。

问题是我必须等待执行才能获得更新的 cron:如果每 15 分钟安排一次作业并且我想将此值更改为每 2 分钟一次,我必须等待下一次执行(最多 15分钟)每 2 分钟完成一次这项工作。

更新数据库后,有没有办法重新安排这项工作?

我想销毁并刷新这个 bean,但它不起作用(也许这是不可能的,或者我的实现中有问题)。也许有一种方法可以触发事件来执行方法configureTask。

这是我预定工作的片段。

@EnableScheduling
@Component
public class MyClass implements SchedulingConfigurer {

    private static final String JOB = "My personal task";

    @Autowired
    JobRepository jobRepository;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello World!");
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                JobScheduled byJobNameIgnoreCase = jobRepository.findByJobNameIgnoreCase(JOB); // read from database 
                String cron = byJobNameIgnoreCase.getCrontab();
                CronTrigger trigger = new CronTrigger(cron);
                return trigger.nextExecutionTime(triggerContext);
            }
        });
    }

}

最佳答案

为了管理这个,我创建了一个 SchedulerOrchestrator 来管理我的工作。这些作业包含一个 SchedulerFuture。

这是我希望可以帮助别人的代码。

让我们从一个将由我的作业实现的接口(interface)开始:

public interface SchedulerObjectInterface {    
    void start();
    void stop();
}

每个作业都需要一个 ScheduledFuture 来停止,并且需要 Autowiring 一个 TaskScheduler 来安排。这是一个工作的示例(您可以创建任意数量的工作):
@Component
public class MyFirstJob implements SchedulerObjectInterface {

    private static final Logger log = LoggerFactory.getLogger(MyFirstJob.class);

    public static final String JOB = "MyFirstJob";

    @Autowired
    JobRepository jobRepository;

    private ScheduledFuture future;

    @Autowired
    private TaskScheduler scheduler;


    @Override
    public void start() {
        future = scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println(JOB + "  Hello World! " + new Date());
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                String cron = cronConfig();
                System.out.println(cron);
                CronTrigger trigger = new CronTrigger(cron);
                return trigger.nextExecutionTime(triggerContext);
            }
        });

    }

    @Override
    public void stop() {
        future.cancel(false);
    }

    // retrieve cron from database
    private String cronConfig() {
        JobScheduled byJobNameIgnoreCase = jobRepository.findByJobNameIgnoreCase(JOB);
        return byJobNameIgnoreCase.getCrontab();
    }

}

最后,我们可以将我们的作业添加到编排器中:
@Configuration
public class SchedulerOrchestrator {

    private static final Logger log = LoggerFactory.getLogger(SchedulerOrchestrator.class);

    private static Map<String, SchedulerObjectInterface> schduledJobsMap = new HashMap<>();

    @Autowired
    JobRepository jobRepository;

    @Autowired
    MyFirstJob myFirstJob;

    @Autowired
    MySecondJob mySecondJob;

    @Autowired
    TaskScheduler scheduler;

    @PostConstruct
    public void initScheduler() {
        schduledJobsMap.put(MyFirstJob.JOB, myFirstJob);
        schduledJobsMap.put(MySecondJob.JOB, mySecondJob);

        startAll();
    }

    public void restart(String job) {
        stop(job);
        start(job);
    }

    public void stop(String job) {
        schduledJobsMap.get(job).stop();
    }

    public void start(String job) {
        schduledJobsMap.get(job).start();
    }

    public void startAll() {
        for (SchedulerObjectInterface schedulerObjectInterface : schduledJobsMap.values()) {
            schedulerObjectInterface.start();
        }
    }

    @Bean
    public TaskScheduler scheduler() {
        return new ThreadPoolTaskScheduler();
    }
}

关于 Spring 更新调度程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41186633/

相关文章:

spring - 如何使用 Vaadin + Spring 创建 MVP 架构?

java - Spring数据库触发器

java - 从嵌入式 jar 中获取应用程序属性 - Spring Boot

java - 在 grpc Spring boot 中关闭自定义线程池执行器

javascript - Telerik Kendo Scheduler 选定的事件详细信息

linux - CFS中vruntime是什么概念

java - 了解 GWT 中推迟的计划

spring - 向 ModelAndView 添加属性

java - Spring 服务器/客户端 session 和 Hibernate session

java - Spring 安全: issues 403 after authorization with single granted