上面几章介绍了quartz监控的几种方式,下面再介绍一种监听方式:自定义QuartzJobBean工具
/** * 定时任务处理 * * @author lipeng * */ @DisallowConcurrentExecution public class ScheduleJob extends QuartzJobBean { private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class); private ThreadPoolTaskExecutor executor = SpringUtils.getBean("threadPoolTaskExecutor"); private final static ISysJobLogService jobLogService = SpringUtils.getBean(ISysJobLogService.class); @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { SysJob job = new SysJob(); BeanUtils.copyBeanProp(job, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); SysJobLog jobLog = new SysJobLog(); jobLog.setJobName(job.getJobName()); jobLog.setJobGroup(job.getJobGroup()); jobLog.setMethodName(job.getMethodName()); jobLog.setMethodParams(job.getMethodParams()); jobLog.setCreateTime(new Date()); long startTime = System.currentTimeMillis(); try { // 执行任务 log.info("任务开始执行 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName()); ScheduleRunnable task = new ScheduleRunnable(job.getJobName(), job.getMethodName(), job.getMethodParams()); Future<?> future = executor.submit(task); future.get(); long times = System.currentTimeMillis() - startTime; // 任务状态 0:成功 1:失败 jobLog.setStatus(Constants.SUCCESS); jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒"); log.info("任务执行结束 - 名称:{} 耗时:{} 毫秒", job.getJobName(), times); } catch (Exception e) { log.info("任务执行失败 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName()); log.error("任务执行异常 - :", e); long times = System.currentTimeMillis() - startTime; jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒"); // 任务状态 0:成功 1:失败 jobLog.setStatus(Constants.FAIL); jobLog.setExceptionInfo(StringUtils.substring(e.getMessage(), 0, 2000)); } finally { jobLogService.addJobLog(jobLog); } } }
SysJobLogui
/** * 定时任务调度日志表 sys_job_log * * @author lipeng */ public class SysJobLog extends BaseEntity { private static final long serialVersionUID = 1L; /** ID */ @Excel(name = "日志序号") private Long jobLogId; /** 任务名称 */ @Excel(name = "任务名称") private String jobName; /** 任务组名 */ @Excel(name = "任务组名") private String jobGroup; /** 任务方法 */ @Excel(name = "任务方法") private String methodName; /** 方法参数 */ @Excel(name = "方法参数") private String methodParams; /** 日志信息 */ @Excel(name = "日志信息") private String jobMessage; /** 执行状态(0正常 1失败) */ @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") private String status; /** 异常信息 */ @Excel(name = "异常信息") private String exceptionInfo; public Long getJobLogId() { return jobLogId; } public void setJobLogId(Long jobLogId) { this.jobLogId = jobLogId; } public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } public String getMethodParams() { return methodParams; } public void setMethodParams(String methodParams) { this.methodParams = methodParams; } public String getJobMessage() { return jobMessage; } public void setJobMessage(String jobMessage) { this.jobMessage = jobMessage; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getExceptionInfo() { return exceptionInfo; } public void setExceptionInfo(String exceptionInfo) { this.exceptionInfo = exceptionInfo; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("jobLogId", getJobLogId()) .append("jobName", getJobName()) .append("jobGroup", getJobGroup()) .append("methodName", getMethodName()) .append("methodParams", getMethodParams()) .append("jobMessage", getJobMessage()) .append("status", getStatus()) .append("exceptionInfo", getExceptionInfo()) .append("createTime", getCreateTime()) .toString(); } }
ScheduleRunnablethis
/** * 执行定时任务 * * @author lipeng * */ public class ScheduleRunnable implements Runnable { private static final Logger log = LoggerFactory.getLogger(ScheduleRunnable.class); private Object target; private Method method; private String params; public ScheduleRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException { this.target = SpringUtils.getBean(beanName); this.params = params; if (StringUtils.isNotEmpty(params)) { this.method = target.getClass().getDeclaredMethod(methodName, String.class); } else { this.method = target.getClass().getDeclaredMethod(methodName); } } @Override public void run() { try { ReflectionUtils.makeAccessible(method); if (StringUtils.isNotEmpty(params)) { method.invoke(target, params); } else { method.invoke(target); } } catch (Exception e) { log.error("执行定时任务 - :", e); } } }
/** * 建立定时任务 */ public static void createScheduleJob(Scheduler scheduler, SysJob job) { try { // 构建job信息 JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build(); // 表达式调度构建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); // 按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId())) .withSchedule(cronScheduleBuilder).build(); // 放入参数,运行时的方法能够获取 jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.scheduleJob(jobDetail, trigger); // 暂停任务 if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (SchedulerException e) { log.error("createScheduleJob 异常:", e); } catch (TaskException e) { log.error("createScheduleJob 异常:", e); } }
/** * 项目启动时,初始化定时器 */ @PostConstruct public void init() { List<SysJob> jobList = jobMapper.selectJobAll(); for (SysJob job : jobList) { CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, job.getJobId()); // 若是不存在,则建立 if (cronTrigger == null) { ScheduleUtils.createScheduleJob(scheduler, job); } else { ScheduleUtils.updateScheduleJob(scheduler, job); } } }
ScheduleUtils源代码以下:.net
/** * 定时任务工具类 * * @author lipeng * */ public class ScheduleUtils { private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class); /** * 获取触发器key */ public static TriggerKey getTriggerKey(Long jobId) { return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId); } /** * 获取jobKey */ public static JobKey getJobKey(Long jobId) { return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId); } /** * 获取表达式触发器 */ public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) { try { return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId)); } catch (SchedulerException e) { log.error("getCronTrigger 异常:", e); } return null; } /** * 建立定时任务 */ public static void createScheduleJob(Scheduler scheduler, SysJob job) { try { // 构建job信息 JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build(); // 表达式调度构建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); // 按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId())) .withSchedule(cronScheduleBuilder).build(); // 放入参数,运行时的方法能够获取 jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.scheduleJob(jobDetail, trigger); // 暂停任务 if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (SchedulerException e) { log.error("createScheduleJob 异常:", e); } catch (TaskException e) { log.error("createScheduleJob 异常:", e); } } /** * 更新定时任务 */ public static void updateScheduleJob(Scheduler scheduler, SysJob job) { try { TriggerKey triggerKey = getTriggerKey(job.getJobId()); // 表达式调度构建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); CronTrigger trigger = getCronTrigger(scheduler, job.getJobId()); // 按新的cronExpression表达式从新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); // 参数 trigger.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.rescheduleJob(triggerKey, trigger); // 暂停任务 if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (SchedulerException e) { log.error("SchedulerException 异常:", e); } catch (TaskException e) { log.error("SchedulerException 异常:", e); } } /** * 当即执行任务 */ public static int run(Scheduler scheduler, SysJob job) { int rows = 0; try { // 参数 JobDataMap dataMap = new JobDataMap(); dataMap.put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.triggerJob(getJobKey(job.getJobId()), dataMap); rows = 1; } catch (SchedulerException e) { log.error("run 异常:", e); } return rows; } /** * 暂停任务 */ public static void pauseJob(Scheduler scheduler, Long jobId) { try { scheduler.pauseJob(getJobKey(jobId)); } catch (SchedulerException e) { log.error("pauseJob 异常:", e); } } /** * 恢复任务 */ public static void resumeJob(Scheduler scheduler, Long jobId) { try { scheduler.resumeJob(getJobKey(jobId)); } catch (SchedulerException e) { log.error("resumeJob 异常:", e); } } /** * 删除定时任务 */ public static void deleteScheduleJob(Scheduler scheduler, Long jobId) { try { scheduler.deleteJob(getJobKey(jobId)); } catch (SchedulerException e) { log.error("deleteScheduleJob 异常:", e); } } public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) throws TaskException { switch (job.getMisfirePolicy()) { case ScheduleConstants.MISFIRE_DEFAULT: return cb; case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: return cb.withMisfireHandlingInstructionIgnoreMisfires(); case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: return cb.withMisfireHandlingInstructionFireAndProceed(); case ScheduleConstants.MISFIRE_DO_NOTHING: return cb.withMisfireHandlingInstructionDoNothing(); default: throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); } } }