我希望能够在Spring中运行SAME预定作业。 在互联网上搜索后,我想出了如何同时运行多个不同的作业。
我有一个@Service注释类,它只有一个方法,用@Scheduled注释。我想让这个作业的多个实例同时运行。
我没有使用Quartz或Spring Batch(我在Spring Batch中看过很多例子)。
文档没有明确说明是否可以实现。
答案 0 :(得分:0)
是的,可以轻松实现,但不能使用@Scheduled
注释。
怎么样?我先来解释一下Spring是如何工作的。
使用@Scheduled
注释的每个方法的Spring都会创建一个新的Runnable
对象,然后将其计划执行到TaskScheduler
(ThreadPoolTaskScheduler
来确切)。
要查看确切的代码,请查看ScheduledAnnotationBeanPostProcessor.processScheduled()
。
所以为了满足你的要求:拥有相同工作的多个实例,但是如果不使用Quartz或Spring Batch,我们需要放弃@Scheduled
注释并做一些与ScheduledAnnotationBeanPostProcessor
做的有点不同的事情。默认值。
@Configuration
public class SpringConfig {
@Autowired
private TaskScheduler scheduler;
@Autowired
private YourServiceAnnotatedClass service;
@PostConstruct
public void startJobs() {
int numOfJobInstances = 3;
List<ImportantJob> jobs = IntStream.range(0, numOfJobInstances)
.mapToObj(i -> new ImportantJob("job" + i, service))
.collect(Collectors.toList());
jobs.forEach(this::schedule);
}
private void schedule(ImportantJob job) {
scheduler.schedule(job, new CronTrigger("*/5 * * * * *"));
// Above CronTrigger with 5 seconds was used, but feel free to use other variants, e.g.
// scheduler.scheduleAtFixedRate()
// scheduler.scheduleWithFixedDelay()
}
@Bean(destroyMethod = "shutdown")
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(3); // Adjust it to your needs
return taskScheduler;
}
}
class ImportantJob implements Runnable {
private final String name;
private final YourServiceAnnotatedClass service;
public ImportantJob(String name, YourServiceAnnotatedClass service) {
this.name = name;
this.service = service;
}
@Override
public void run() {
service.doSth();
}
}
正如您所看到的,尽管@Scheduled
有用且简单,但它不是很灵活。但通过一些努力,您可以更好地控制计划任务。