由于业务需要得实现一个周期性的自动执行任务,之前的话都是在启动类上使用@EnableScheduling,然后定义一个自动任务类,在方法上使用@Scheduled(cron = "${job.archive.cron}"),来实现功能需要,这次就想换种方式实现,采用实现CommandLineRunner接口,这个接口在启动完成后,会自动执行run方法,我准备在run方法里使用周期线程池,来周期性执行。
java@Component
public class AutoReturnTaskRunner implements CommandLineRunner {
Logger logger = LoggerFactory.getLogger(this.getClass());
private List<AutoReturnRequest> taskList=new ArrayList<>();
private ScheduledExecutorService scheduler= Executors.newScheduledThreadPool(1);
@Resource
private IHdpParameterTService iHdpParameterTService;
@Resource
private IRecReturnLogService iRecReturnLogService;
@Resource
private IRecMrIndexService iRecMrIndexService;
@Override
public void run(String... args) throws Exception {
// 周期性地检查任务列表并执行任务
scheduler.scheduleAtFixedRate(() -> {
logger.info("开始自动执行返修病人的归档和签收操作---------------------");
logger.info("检查数据库配置任务开关是否开启!");
QueryWrapper<HdpParameterTEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(HdpParameterTEntity::getConfigName, "RETURN_SCHEDULER_ENABLE");
HdpParameterTEntity parameterT = iHdpParameterTService.getOne(queryWrapper);
if (ObjectUtil.isNull(parameterT)) {
logger.info("未检测开关配置,任务终止---------------------1小时后重试");
} else {
if (StrUtil.isNotBlank(parameterT.getConfigValue())) {
if ("false".equals(parameterT.getConfigValue())) {
logger.info("开关为关闭状态,任务终止---------------------1小时后重试");
} else if ("true".equals(parameterT.getConfigValue())) {
logger.info("开关为开启状态,任务开始----------------------");
if (taskList.isEmpty()) {
// 从数据库中获取任务并添加到列表中
taskList = iRecReturnLogService.getAutoTaskList();
if (CollUtil.isEmpty(taskList)) {
logger.info("数据库中还未发现返修后需要自动归档、签收数据,1小时后重试");
}
} else {
// 执行任务列表中的任务
Iterator<AutoReturnRequest> iterator = taskList.iterator();
while (iterator.hasNext()) {
AutoReturnRequest task = iterator.next();
Date now = new Date();
if (now.compareTo(task.getReturnTimeEnd()) > 0) {
//当前时间大于该患者归档截止
QueryWrapper<RecMrIndexEntity> queryrIndexWrapper = new QueryWrapper();
queryrIndexWrapper.lambda().eq(RecMrIndexEntity::getPatientId, task.getPatientId()).eq(RecMrIndexEntity::getVisitNo, task.getVisitNo());
RecMrIndexEntity entity = iRecMrIndexService.getOne(queryrIndexWrapper);
if (entity.getPaperReceiveStatus() == 0 && entity.getArchiveStatus() == 0) {
entity.setMrStatus("A");
entity.setArchiveTime(now);
if (entity.getFirstArchiveTime() == null) {
entity.setFirstArchiveTime(now);
}
entity.setArchiveDoctorId("9999");
entity.setArchiveDoctor("自动任务");
entity.setArchiveStatus(1);
entity.setPaperReceiveStatus(1);
entity.setReceiveTime(now);
entity.setReceiveDoctorId("9999");
entity.setReceiveDoctor("自动任务");
}
boolean result = iRecMrIndexService.updateById(entity);
if (result) {
iterator.remove();
}
}
}
logger.info("当前所有任务执行完毕-------------1小时后再次运行任务");
}
} else {
logger.info("开关配置错误,任务终止---------------------1小时后重试");
}
} else {
logger.info("未检测开关配置,任务终止---------------------1小时后重试");
}
}
}, 0, 60, TimeUnit.MINUTES); // 每1小时执行一次任务
}
public void stop() {
scheduler.shutdown();
}
}
可以实现对任务执行的精准控制,编写控制方法后,调用stop和run方法就可以在前台页面通过按钮对任务执行状况进行精准控制.
可以将经过某些操作后需要处理的任务添加到redis中,处理列表为空的先去redis中获取,避免老是查询数据库,提高执行的效率
本文作者:Weee
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!