SpringBoot整合Quartz

写在前面:本项目环境springboot+spring data jpa
Quartz核心概念:
Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:void execute(JobExecutionContext context)
JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
Trigger 代表一个调度参数的配置,什么时候去调。
Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

1.新建任务表并添加记录


image.png

2.配置类


image.png

3.实现ApplicationRunner方法,在程序启动的时候执行任务注入


image.png

4.构建Job,根据cron创建Trigger触发器
@Slf4j
@Component
public class QuartzManage {

private static final String JOB_NAME = "TASK_";

@Resource(name = "scheduler")
private Scheduler scheduler;

public void addJob(QuartzJob quartzJob){
    try {
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class).
                withIdentity(JOB_NAME + quartzJob.getId()).build();

        //通过触发器名和cron 表达式创建 Trigger
        Trigger cronTrigger = newTrigger()
                .withIdentity(JOB_NAME + quartzJob.getId())
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()))
                .build();

        cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob);

        //重置启动时间
        ((CronTriggerImpl)cronTrigger).setStartTime(new Date());

        //执行定时任务
        scheduler.scheduleJob(jobDetail,cronTrigger);

        // 暂停任务
        if (quartzJob.getIsPause()) {
            pauseJob(quartzJob);
        }
    } catch (Exception e){
        log.error("创建定时任务失败", e);
        throw new BadRequestException("创建定时任务失败");
    }
}

5.执行任务
@Async
public class ExecutionJob extends QuartzJobBean {

private Logger logger = LoggerFactory.getLogger(this.getClass());

private ExecutorService executorService = Executors.newSingleThreadExecutor();

@Override
protected void executeInternal(JobExecutionContext context) {
    QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);
    // 获取spring bean
    QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean("quartzLogRepository");
    QuartzJobService quartzJobService = SpringContextHolder.getBean("quartzJobService");
    QuartzManage quartzManage = SpringContextHolder.getBean("quartzManage");

    QuartzLog log = new QuartzLog();
    log.setJobName(quartzJob.getJobName());
    log.setBeanName(quartzJob.getBeanName());
    log.setMethodName(quartzJob.getMethodName());
    log.setParams(quartzJob.getParams());
    long startTime = System.currentTimeMillis();
    log.setCronExpression(quartzJob.getCronExpression());
    try {
        // 执行任务
        logger.info("任务准备执行,任务名称:{}", quartzJob.getJobName());
        QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
                quartzJob.getParams());
        Future future = executorService.submit(task);
        future.get();
        long times = System.currentTimeMillis() - startTime;
        log.setTime(times);
        // 任务状态
        log.setIsSuccess(true);
        logger.info("任务执行完毕,任务名称:{} 总共耗时:{} 毫秒", quartzJob.getJobName(), times);
    } catch (Exception e) {
        logger.error("任务执行失败,任务名称:{}" + quartzJob.getJobName(), e);
        long times = System.currentTimeMillis() - startTime;
        log.setTime(times);
        // 任务状态 0:成功 1:失败
        log.setIsSuccess(false);
        log.setExceptionDetail(ThrowableUtil.getStackTrace(e));
        //出错就暂停任务
        quartzManage.pauseJob(quartzJob);
        //更新状态
        quartzJobService.updateIsPause(quartzJob);
    } finally {
        quartzLogRepository.save(log);
    }
}

}

/**

  • 执行定时任务

  • @author
    */
    @Slf4j
    public class QuartzRunnable implements Runnable {

    private Object target;
    private Method method;
    private String params;

    QuartzRunnable(String beanName, String methodName, String params)
    throws NoSuchMethodException, SecurityException {
    this.target = SpringContextHolder.getBean(beanName);
    this.params = params;

     if (StringUtils.isNotBlank(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.isNotBlank(params)) {
    method.invoke(target, params);
    } else {
    method.invoke(target);
    }
    } catch (Exception e) {
    log.error("定时任务执行失败",e);
    }
    }

}

6.测试类:


image.png

7.晚安。

你可能感兴趣的:(SpringBoot整合Quartz)