Quartz定时任务项目中应用

文章介绍了如何在SpringBoot项目中集成Quartz实现定时任务,包括使用MySQL存储任务信息,配置application.yml,以及创建JobService接口和其实现类,用于动态管理任务的添加、暂停、恢复和删除。同时,文章还展示了如何定义可执行的Job类并使用Cron表达式设置执行时间。
摘要由CSDN通过智能技术生成

Quartz定时任务项目中应用

一.数据库表准备

Quartz 存储任务信息有两种方式,使用内存或者使用数据库来存储,这里我们采用 MySQL 数据库存储的方式,首先需要新建 Quartz 的相关表,sql 脚本下载地址:http://www.quartz-scheduler.org/downloads/,名称为 tables_mysql.sql,创建成功后数据库中多出 11 张表

二.依赖导入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

三.application.yml配置

# 定时任务配置
sprinng:
  quartz:
    #数据库方式
    job-store-type: jdbc
    # quartz 相关属性配置
    properties:
      org:
        quartz:
          scheduler:
            instanceName: examScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_
            isClustered: true
            clusterCheckinInterval: 10000
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

四.自定义实现类实现自定义接口

4.1 引入Scheduler

/**
     * Quartz定时任务核心的功能实现类
     */
    private Scheduler scheduler;

    /**
     * 注入
     * @param schedulerFactoryBean
     */
    public JobServiceImpl(@Autowired SchedulerFactoryBean schedulerFactoryBean) {
        scheduler = schedulerFactoryBean.getScheduler();
    }

4.2定义接口JobService

/**
 * 任务业务类,用于动态处理任务信息
 * @author bool 
 * @date 2020/11/29 下午2:17
 */
public interface JobService {


    /**
     * 任务数据
     */
    String TASK_DATA = "taskData";

    /**
     * 添加定时任务
     * @param jobClass
     * @param jobName
     * @param jobGroup
     * @param cron
     * @param data
     */
    void addCronJob(Class jobClass, String jobName, String jobGroup, String cron, String data);

    /**
     * 添加立即执行的任务
     * @param jobClass
     * @param jobName
     * @param jobGroup
     * @param data
     */
    void addCronJob(Class jobClass, String jobName, String jobGroup, String data);

    /**
     * 暂停任务
     * @param jobName
     * @param jobGroup
     */
    void pauseJob(String jobName, String jobGroup);

    /**
     * 恢复任务
     * @param triggerName
     * @param triggerGroup
     */
    void resumeJob(String triggerName, String triggerGroup);

    /**
     * 删除job
     * @param jobName
     * @param jobGroup
     */
    void deleteJob(String jobName, String jobGroup);
}

4.3定义实现类JobServiceImpl

@Service
public class JobServiceImpl implements JobService {

    /**
     * Quartz定时任务核心的功能实现类
     */
    private Scheduler scheduler;

    /**
     * 注入
     * @param schedulerFactoryBean
     */
    public JobServiceImpl(@Autowired SchedulerFactoryBean schedulerFactoryBean) {
        scheduler = schedulerFactoryBean.getScheduler();
    }


    @Override
    public void addCronJob(Class jobClass, String jobName, String jobGroup, String cron, String data) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail != null) {
                log.info("++++++++++任务:{} 已存在", jobName);
                this.deleteJob(jobName, jobGroup);
            }

            log.info("++++++++++构建任务:{},{},{},{},{} ", jobClass.toString(), jobName, jobGroup, cron, data);

            //构建job信息
            jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();
            //用JopDataMap来传递数据
            jobDetail.getJobDataMap().put(TASK_DATA, data);

            //表达式调度构建器(即任务执行的时间,每5秒执行一次)
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, trigger);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addCronJob(Class jobClass, String jobName, String jobGroup, String data) {

        // 随机3-8秒后执行
        java.util.Calendar cl = java.util.Calendar.getInstance();
        cl.setTimeInMillis(System.currentTimeMillis());
        cl.add(Calendar.SECOND, 3 + new Random().nextInt(5));

        this.addCronJob(jobClass, jobName, jobGroup, CronUtils.dateToCron(cl.getTime()), data);
    }


    @Override
    public void pauseJob(String jobName, String jobGroup) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
            scheduler.pauseTrigger(triggerKey);
            log.info("++++++++++暂停任务:{}", jobName);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void resumeJob(String jobName, String jobGroup) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
            scheduler.resumeTrigger(triggerKey);
            log.info("++++++++++重启任务:{}", jobName);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteJob(String jobName, String jobGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName,jobGroup);
            scheduler.deleteJob(jobKey);
            log.info("++++++++++删除任务:{}", jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

4.4 业务需要执行的定时方法

我们自己如果需要执行一个定时方法需要实现Job接口,重写execute方法,例子如下:
我们可以写多个这种类,供我们执行不同的定时操作任务!

@Component
public class AddBookJob implements Job {

    @Autowired
    private PaperQuService paperQuService;

    @Autowired
    private UserBookService userBookService;
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDetail detail = jobExecutionContext.getJobDetail();
        String name = detail.getKey().getName();
        String group = detail.getKey().getGroup();
        String data = String.valueOf(detail.getJobDataMap().get(JobService.TASK_DATA));
        log.info("++++++++++定时任务:考完加入错题本");
        log.info("++++++++++jobName:{}", name);
        log.info("++++++++++jobGroup:{}", group);
        log.info("++++++++++taskData:{}", data);
        // 转换数据,id为试卷id,examId为考试ID
        PaperDTO dto = JSON.parseObject(data, PaperDTO.class);
        // 错题列表
        List<String> ids = paperQuService.listWrongIds(dto.getId());
        for (String id : ids) {
            //加入错题本
            userBookService.addBook(dto.getUserId(), dto.getExamId(), id);
        }
    }
}

addCronJob 函数参数解释

业务中调用时使用注入的上文中接口类jobService,调用addCroJob方法实现方.

jobService.addCronJob(AddBookJob.class, bookName, JobGroup.SYSTEM, JSON.toJSONString(dto)); //业务中调用


	@Override
    public void addCronJob(Class jobClass, String jobName, String jobGroup, String cron, String data) {
        //参数解释
        //1.jobClass 就是我们自己定义的需要定时执行的类
        //2.jobName 自定义的该任务的Key
        //3.jobGroup 自定义的分组
        //4.cron 就是Cron表达式,通常使用下述Cron工具类直接调用
        //5.data 是在业务中需要传到我们自己定义的需要执行的类中的数据(上文中会将该数据存储在表示execute方法中的jobExecutionContext中)
    }

CronUtils 工具类

public class CronUtils {

    /**
     * 格式化数据
     */
    private static final String DATE_FORMAT = "ss mm HH dd MM ? yyyy";

    /**
     * 准确的时间点到表达式
     * @param date
     * @return
     */
    public static String dateToCron(final Date date){
        SimpleDateFormat fmt = new SimpleDateFormat(DATE_FORMAT);
        String formatTimeStr = "";
        if (date != null) {
            formatTimeStr = fmt.format(date);
        }
        return formatTimeStr;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闪耀太阳a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值