java spring boot 动态添加 cron(表达式)任务、动态添加停止单个cron任务
-
添加对应的maven
XML<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency>
-
添加一个工具类 SchedulerManager
javaimport org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory; public class SchedulerManager { private static Scheduler scheduler; // 初始化 Scheduler public static void initScheduler() throws SchedulerException { SchedulerFactory schedulerFactory = new StdSchedulerFactory(); scheduler = schedulerFactory.getScheduler(); // 为了方便直接创建后启用 scheduler.start(); } // 使用同步块确保线程安全 public static Scheduler getScheduler() { if (scheduler == null) { synchronized (SchedulerManager.class) { if (scheduler == null) { // 双重检查 try { initScheduler(); } catch (SchedulerException e) { // 处理异常或抛出自定义异常 e.printStackTrace(); } } } } return scheduler; } // 启动 scheduler public static void start() { try { if (!scheduler.isStarted()) { scheduler.start(); } } catch (SchedulerException e) { // 处理异常或抛出自定义异常 e.printStackTrace(); } } // 暂停任务/删除任务 public static void stopTask(String jobKey) { try { Scheduler scheduler = SchedulerManager.getScheduler(); JobKey key = new JobKey(jobKey, jobKey); JobDetail jobDetail = scheduler.getJobDetail(key); if (jobDetail != null) { // 获取JobDataMap JobDataMap dataMap = jobDetail.getJobDataMap(); dataMap.put("ok", false); // 暂停任务 scheduler.pauseJob(key); // 或者删除当前任务 // scheduler.deleteJob(key); } } catch (SchedulerException e) { e.printStackTrace(); } } // 恢复任务 public static int startTask(String jobKey) { int o = 0; try { Scheduler scheduler = SchedulerManager.getScheduler(); JobKey key = new JobKey(jobKey, jobKey); JobDetail jobDetail = scheduler.getJobDetail(key); if (jobDetail != null) { // 获取JobDataMap JobDataMap dataMap = jobDetail.getJobDataMap(); dataMap.put("ok", true); // 恢复任务 scheduler.resumeJob(key); o = 1; } } catch (SchedulerException e) { e.printStackTrace(); }finally { return o; } } /** * 停止所有任务 */ public static void stopAllTask() { try { Scheduler scheduler = context.getScheduler(); try { // 停止调度器 scheduler.shutdown(); } catch (SchedulerException e) { logger.error("停止调度器时出错", e); throw new JobExecutionException("停止调度器时出错", e); } } catch (SchedulerException e) { e.printStackTrace(); } } }
-
添加cron执行任务类
javaimport lombok.extern.slf4j.Slf4j; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.Date; @Component @Slf4j @Service public class CronThread implements Job { private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); // 详情id String detailId = ""; // 启用/停用(双重保险) boolean ok = true; // 设备id int facilityId = -1; public void setOK(boolean ok) { this.ok = ok; } @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { JobDataMap dataMap = context.getJobDetail().getJobDataMap(); // 获取参数,注意数据类型 this.ok = dataMap.getBoolean("ok"); if (ok){ this.detailId = dataMap.getString("detailId"); this.facilityId = dataMap.getInt("facilityId"); logger.info("任务执行: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "。key=" + context.getJobDetail().getKey()); frameSave(); } } catch (Exception e) { logger.error("执行任务异常,内容", e); logger.info("停止任务:{}",context.getJobDetail().getKey()); Scheduler scheduler = context.getScheduler(); try { // 暂停当前任务 // scheduler.pauseJob(context.getJobDetail().getKey()); // 或者删除当前任务 scheduler.deleteJob(context.getJobDetail().getKey()); } catch (SchedulerException s) { logger.error("暂停或删除任务时出错", s); throw new JobExecutionException("暂停或删除任务时出错", s); } } } public void frameSave() { try { logger.info("执行任务"); } catch (Exception e) { logger.error("执行异常,内容: ", e); } } }
-
启动/使用 方式
java// 启动全部 public void startAllTasks(List<Map<String,Object>> mapList){ // 获取scheduler Scheduler scheduler = SchedulerManager.getScheduler(); for (Map<String, Object> map : mapList) { try { // 像任务执行类传入参数 JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("detailId", map.get("detailId").toString()); jobDataMap.put("facilityId", (int) map.get("detailId")); jobDataMap.put("ok", true); // 任务唯一标识 根据情况来定,后续停止或启用单个的时候需要用到该key值 String key = map.get("detailId").toString() + "-" + map.get("facilityId").toString(); // 上面创建的 cron 执行任务类(CronThread.class) JobDetail jobDetail = JobBuilder.newJob(CronThread.class) .withIdentity(key, key) .setJobData(jobDataMap) .build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity(key, key) .withSchedule(CronScheduleBuilder.cronSchedule(map.get("cronStr").toString()))//cron表达式 .build(); // 添加任务 到时间后会自动调用(在上面获取scheduler时里面有启动的操作) scheduler.scheduleJob(jobDetail, trigger); } catch (Exception e){ e.printStackTrace(); logger.error("启动抽帧任务报错:: ", e); } } } // 停止单个任务 public void stopOneTask(String detailId,int facilityId){ // 任务唯一标识 String key = detailId + "-" + facilityId; SchedulerManager.stopTask(key); } // 启动单个任务 public int startOneTask(String detailId,int facilityId,String cronStr){ // 任务唯一标识 String key = detailId + "-" + facilityId; int i = SchedulerManager.startTask(detailId + "-" + facilityId); if (i == 0) { // 该任务已被删除 重新添加 try { // 可以将下面代码封装成一个方法,否则会和上面启动全部任务的操作代码重复 JobKey jobKey = new JobKey(key, key); Scheduler scheduler = SchedulerManager.getScheduler(); if (scheduler.checkExists(jobKey)) { return 1; } JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("detailId", detailId); jobDataMap.put("facilityId", facilityId); jobDataMap.put("ok", true); JobDetail jobDetail = JobBuilder.newJob(CronThread.class) .withIdentity(key, key) .setJobData(jobDataMap) .build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity(key, key) .withSchedule(CronScheduleBuilder.cronSchedule(cronStr)) .build(); scheduler.scheduleJob(jobDetail, trigger); return 1; } catch (SchedulerException e) { // 处理调度器异常 e.printStackTrace(); logger.error("One Scheduler exception: ", e); return 0; } } return 0; }