我在Spring有一份预定的工作,我从数据库中得到了它的时间表。每次执行时,下一次执行时间都会更新。因此,如果将其配置为每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。
我希望这里的代码可以对其他人有所帮助。
让我们从将由我的工作实现的接口开始:
public interface SchedulerObjectInterface { void start(); void stop(); }
每个作业都需要一个ScheduledFuture才能停止,并且需要自动连接一个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(); } }