问题描述
我在春季有一份预定的工作,我从数据库中得到了它的cron.每次执行时,下一次执行时间都会更新.因此,如果将其配置为每10分钟运行一次,那么我可以将值更改为数据库,以每15分钟安排一次该作业.
I have a scheduled job in Spring, I get its cron from my database.Every time it is executed, the next execution time is updated. So, if it is configured to run every 10 minutes, I can change the value into the database to schedule that job every 15 minutes.
问题是我必须等待执行以获取更新的cron:如果每15分钟安排一次作业,并且要将此值更改为每2分钟,则必须等待下一次执行(最多15分钟)以每2分钟完成一次这项工作.
The problem is that I have to wait for the execution to get the updated cron: if a job is scheduled every 15 minutes and I want to change this value to be every 2 minutes, I have to wait for the next execution (up to 15 minutes) to have this job every 2 minutes.
在更新数据库之后,是否有办法重新安排此作业的时间?
Is there a way to get this job rescheduled after I update the database?
我曾想破坏并刷新此bean,但是它不起作用(也许是不可能的,或者在我的实现中出了点问题).也许有一种触发事件的方法来执行configureTask的方法.
I thought to destroy and refresh this bean, but it is not working (maybe it is not possible or something was wrong in my implementation). Maybe there is a way to trigger an event to execute method configureTask.
这是我预定工作的摘要.
Here the snippet of my scheduled job.
@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.
To manage this, I created a SchedulerOrchestrator, which manages my jobs. The jobs contain a SchedulerFuture.
这是我希望可以帮助别人的代码.
Here the code that I hope can help someone else.
让我们从一个将由我的工作实现的界面开始:
Let's start with an interface which will be implemented by my jobs:
public interface SchedulerObjectInterface {
void start();
void stop();
}
每个作业都需要一个ScheduledFuture才能停止,并且需要自动连接一个TaskScheduler以进行调度.这里是一份工作的示例(您可以创建任意数量的工作):
Every job needs a ScheduledFuture to stop and needs to autowire a TaskScheduler to be scheduled. Here a sample of one job (you can create as many as you want):
@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();
}
}
最后,我们可以将工作添加到协调器中:
Finally we can add our jobs to an orchestrator:
@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();
}
}
这篇关于春季更新调度程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!