【开发需求】
每天在tb_base_uplod_cfg表中设定运行时间开始执行,此后设定值修改需立即生效,无需启动程序!
具体实现
- 在启动类上添
@EnableScheduling注解 - 实现
SchedulingConfigurer接口 - 重写
SchedulingConfigurer接口的configureTasks方法
【代码演示】
@Slf4j
@Component
public class RealTimeStatisticalDataCalculationJob implements SchedulingConfigurer {
@Autowired
private RealTimeStatisticalDataCalculationJobService realTimeStatisticalDataCalculationJobService;
@Autowired
private BaseStatisticUploadCfgRepository baseStatisticUploadCfgRepository;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(this::execute, triggerContext -> new CronTrigger(getCron()).nextExecutionTime(triggerContext));
}
private String getCron() {
BaseStatisticUploadCfg job = baseStatisticUploadCfgRepository.findAllByName("RealTimeStatisticalDataCalculationJob");
return job.getCron();
}
private void execute() {
final String lockKey = ConstantUtil.REDIS_KEY_JS_KECE_EOMS_CLIENT_REAL_TIME_STATISTICAL_DATA_CALCULATION_TASK_LOCK;
long s = System.currentTimeMillis();
String taskId = UUID.randomUUID().toString();
log.info("实时统计数据定时计算任务开始执行,本次任务ID:{}", taskId);
// 具体代码实现逻辑
log.info("实时统计数据定时计算任务完成,耗时: {} ms", (System.currentTimeMillis() - s));
}
}
上述方法虽然能够实现不用重启项目,但没有做到实时监测数据库中修改。只有在定时任务下次执行时调用getCron()方法时获取到新的cron表达式,之后就使用修改后的cron执行定时任务。因此使用下面方式来实现该功能需求
配置TaskSchedulerConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler; `
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class TaskSchedulerConfig {
@Bean(name = "myTaskScheduler")
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("MessageBroker-");
scheduler.setPoolSize(Runtime.getRuntime().availableProcessors());
scheduler.setRemoveOnCancelPolicy(true);
scheduler.initialize();
return scheduler;`
}
}
@Slf4j
@Component
public class RealTimeStatisticalDataCalculationJob {
@Autowired
private RealTimeStatisticalDataCalculationJobService realTimeStatisticalDataCalculationJobService;
@Autowired
private BaseStatisticUploadCfgRepository baseStatisticUploadCfgRepository;
@Autowired
@Qualifier("myTaskScheduler")
private TaskScheduler taskScheduler;
private static final Map<String, ScheduledFuture<?>> JOB = new HashMap<>();
@PostConstruct
public void scheduleAllJobs() {
// 创建定时任务
createJob();
}
/**
* 新增调用该方法,创建定时任务
*/
public void createJob() {
// 创建任务
// 执行任务逻辑
Runnable job = this::execute;
// 根据cron字段创建CronTrigger触发器
CronTrigger cronTrigger = new CronTrigger(getCron());
// 安排定时任务
ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(job, cronTrigger);
// 将任务加入到scheduledJobs映射中
JOB.put("RealTimeStatisticalDataCalculationJob", scheduledFuture);
}
/**
* 更新表中记录,调用该方法
*/
public void updateJob() {
// 取消旧的定时任务
cancelJob("RealTimeStatisticalDataCalculationJob");
// 创建新的定时任务
createJob();
}
/**
* 删除表中记录,调用该方法
*
* @param key 定时任务标识
*/
public void deleteJob(String key) {
// 取消定时任务
cancelJob(key);
// 从scheduledJobs映射中移除任务
JOB.remove(key);
}
/**
* 取消定时任务
*
* @param key 定时任务标识
*/
private void cancelJob(String key) {
ScheduledFuture<?> scheduledFuture = JOB.get(key);
// 取消任务
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
}
private String getCron() {
List<BaseStatisticUploadCfgEntity> baseStatisticUploadCfgList = baseStatisticUploadCfgRepository.findAll();
if (StringUtils.isNullOrEmpty(baseStatisticUploadCfgList)){
log.error("未配置统计上报配置信息对象,本次任务结束!");
return "-";
}
BaseStatisticUploadCfgEntity baseStatisticUploadCfg = baseStatisticUploadCfgList.get(0);
// 查询tb_base_statistic_upload_cfg表中的 【实时数据统计周期(分钟)】值 和 【实时统计延迟运行分钟数】值
if (baseStatisticUploadCfg != null&& baseStatisticUploadCfg.getRealDataStatPeriods() != null && baseStatisticUploadCfg.getRealStatDelayRunMinutes() != null){
// 实时数据统计周期(分钟)
Integer realDataStatPeriods = baseStatisticUploadCfg.getRealDataStatPeriods();
// 实时统计延迟运行分钟数
Integer realStatDelayRunMinutes = baseStatisticUploadCfg.getRealStatDelayRunMinutes();
return "0 " + realStatDelayRunMinutes + "/" + realDataStatPeriods + " * * * ?";
}
return "-";
}
/**
* 任务功能实现
*/
private void execute() {
long s = System.currentTimeMillis();
String taskId = UUID.randomUUID().toString();
log.info("实时统计数据定时计算任务开始执行,本次任务ID:{}", taskId);
realTimeStatisticalDataCalculationJobService.realTimeStatisticalDataCalculation();
log.info("实时统计数据定时计算任务完成,耗时: {} ms", (System.currentTimeMillis() - s));
}
}