我计划使用 Spring Boot 的 @Scheduler 注解来运行 cron 作业来执行各种任务。目前,该作业只是每分钟打印“Hello”。我有一张详细说明 cron 作业的表,其中为 cron 表达式保留一列,例如 0 * * * * *。该表达式从表中检索并用于安排 cron 作业。我的目的是通过数据库而不是通过代码更改来启用间隔更新。
当前实现可以工作,但作业仅运行一次,无法再次运行。我已经检查了断点并记录了作业首次运行的日志时间,但不幸的是它没有再次运行
private void getCronDetails() {
//Returns map of <cronjobName, cronSchedule> e.g. <myJobName, "0 * * * * *">
List<Map<String, String>> schedulesFromDBList = cronJobRepository.getCronJobSchedule();
for (Map<String, String> scheduleMap : schedulesFromDBList) {
String cronJobName = scheduleMap.get(JobName);
String cronSchedule = scheduleMap.get(CronSchedule);
cronJobSchedules.put(cronJobName, cronSchedule);
}
}
@Scheduled(cron = "#{@cronJobSchedules.get('MyJobName')}", zone = TIME_ZONE, initialDelayString = "#{@initialDelay}")
public void accountCleanupJob() {
System.out.println("hello");
}
Map 包含作业名称和 cron 计划。额外的逻辑是使用作业名称完成的,但这不是必需的。该作业仅运行一次,除非我有“initialDelayString”,否则无法开始
我应该更改为固定表达式而不是从数据库检索吗?
在不使用
@Scheduled
注释之前我已经达到了这个要求,但像这样:
org.springframework.scheduling.annotation.SchedulingConfigurer
void configureTasks(ScheduledTaskRegistrar taskRegistrar)
类似这样的:
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class ScheduleManager implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// read from DB...
List<Map<String, String>> schedulesFromDBList = cronJobRepository.getCronJobSchedule();
for (Map<String, String> scheduleMap : schedulesFromDBList) {
String cronJobName = scheduleMap.get(JobName);
String cronSchedule = scheduleMap.get(CronSchedule);
taskRegistrar.addCronTask(
new CronTask(this::myTask, cronSchedule)
);
}
}
private void myTask() {
System.out.println("hello");
}
}
如果您需要动态响应更改的任务计划,则需要进行一些调整。