java每小时调动一次,生成任务,基于corn表达式动态调动任务执行
该代码是一个基于Spring框架实现的动态巡检任务调度器,核心功能是支持巡检任务的动态管理(包括新增、更新、删除和查询),并根据数据库配置自动调度任务执行。主要应用技术和功能特点如下:
核心功能
1、动态任务调度:通过实现SchedulingConfigurer接口,结合ScheduledTaskRegistrar管理任务注册,支持从数据库动态加载、更新和移除巡检任务,无需重启应用即可生效。
2、定时配置刷新:使用@Scheduled(cron = "0 2 * * * ?")注解,每30秒从数据库同步最新任务配置(查询executeType="0"的启用任务),确保任务配置实时生效。
3、任务生命周期管理:通过ConcurrentHashMap(taskMap)缓存任务ID与ScheduledFuture对象,支持任务的取消(oldFuture.cancel(false))、新增(newFuture注册)和自动清理(移除已禁用/删除的任务)。
4、特殊任务自动处理:针对inspectionType="2"的特殊巡检任务,执行后自动将状态更新为禁用(executeType="2")并从缓存移除,避免重复调度。应用技术
1、Spring任务调度:基于SchedulingConfigurer接口和@Scheduled注解实现定时任务框架,结合ScheduledTaskRegistrar管理任务注册与调度。
2、Cron表达式:使用CronTrigger解析任务的cronExpression字段,支持复杂时间规则(如周期性任务调度)。
3、并发安全:通过ConcurrentHashMap存储任务缓存,确保多线程环境下任务管理的线程安全。
4、数据库交互:通过DtInspectionTaskDao访问数据库,动态查询和更新任务状态(如启用/禁用、特殊任务执行后状态更新)。
5、日志与监控:使用SLF4J日志框架记录任务调度状态(如任务注册成功/失败、执行日志),便于问题排查和监控。
代码如下:
package com.jeesite.modules.task.inspection;import com.jeesite.modules.dt.dao.DtInspectionTaskDao;
import com.jeesite.modules.dt.entity.DtInspectionTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;/*** 动态巡检任务调度器(支持任务动态增删改查)*/
@Service
public class DynamicTaskScheduler implements SchedulingConfigurer {Logger logger = LoggerFactory.getLogger(DynamicTaskScheduler.class);@Autowiredprivate DtInspectionTaskDao taskDao; // 任务数据库访问层private final Map<String, ScheduledFuture<?>> taskMap = new ConcurrentHashMap<>(); // 任务缓存(ID→Future)private ScheduledTaskRegistrar taskRegistrar; // 调度器注册器(保存实例避免NPE)// 初始化:应用启动时加载所有启用任务@Overridepublic void configureTasks(ScheduledTaskRegistrar registrar) {this.taskRegistrar = registrar;refreshTasks(); // 首次加载任务}// 定时刷新:每30秒从数据库同步最新任务配置 0 2 * * * ? | 0 0/5 * * * ?@Scheduled(cron = "0 2 * * * ?")public void refreshTaskConfig() {refreshTasks();}/*** 核心:刷新任务(新增/更新/删除)*/private void refreshTasks() {if (taskRegistrar == null || taskRegistrar.getScheduler() == null) {logger.error("调度器未初始化,跳过任务刷新");return;}// 1. 查询数据库中所有启用的任务DtInspectionTask query = new DtInspectionTask();query.setExecuteType("0");List<DtInspectionTask> activeTasks = taskDao.findList(query);// 2. 处理每个启用任务(新增/更新)for (DtInspectionTask task : activeTasks) {try {// 任务执行逻辑Runnable taskRunnable = () -> executeTask(task);// 取消旧任务(若存在)if (taskMap.containsKey(task.getId())) {ScheduledFuture<?> oldFuture = taskMap.get(task.getId());if (!oldFuture.isCancelled()) {oldFuture.cancel(false); // 不中断正在执行的任务}}// 根据任务类型选择触发器ScheduledFuture<?> newFuture;String cron = task.getCronExpression();newFuture = taskRegistrar.getScheduler().schedule(taskRunnable, new CronTrigger(cron));// 更新任务缓存taskMap.put(task.getId(), newFuture);logger.info("任务[{}]调度成功(类型:{}){}", task.getPlanName(), task.getInspectionType(),task.getId());} catch (Exception e) {logger.error("任务[{}](ID:{})调度失败:{}{}", task.getPlanName(), task.getId(), e.getMessage(), e);}}// 3. 移除已禁用/删除的任务(数据库中不存在的启用任务)taskMap.keySet().removeIf(taskId ->activeTasks.stream().noneMatch(t -> t.getId().equals(taskId)));}/*** 任务执行逻辑*/private void executeTask(DtInspectionTask task) {logger.info("[{}] 开始执行执行巡检任务:{}(ID:{})(类型:{})", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), task.getPlanName(), task.getId(), task.getInspectionType());// 特殊任务执行后自动禁用(避免重复调度)if ("2".equals(task.getInspectionType())) {task.setExecuteType("2");taskDao.update(task); // 更新数据库状态taskMap.remove(task.getId()); // 从缓存移除logger.info("特殊任务执行后自动禁用(避免重复调度):{}", task.getPlanName());}// TODO: 实际巡检逻辑(如调用设备接口、发送指令等)}
}