SpringBoot中Quarz的使用

前言:

今天主要简单的讲一下Quarz任务框架的使用。

          现在有个需求,需要做一个提醒功能,相当于一个闹钟功能,举个例子:5点处理企业微信上未读消息,6点对数据进行备份。

一般情况下定时定点的定时任务直接用@Schedule   ,也可以用Timer ,给Timer设置时间,存在缺陷,通过同时执行俩个任务的话,如果第一个任务报错了,那么第二个任务就直接挂掉了。 这么一分析的话,我就想到了用Quarz ,因为它的任务是动态的,我只需要管理这些任务。以下俩种方式都可实现,第一种方式更加灵活,灵活设置执行时间,第二种是与Spingboot的结合。

一.介绍Quarz

几个核心的点:

  1. Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下: 你要做什么事?
    void execute(JobExecutionContext context) 
  2. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
  3. Trigger 代表一个调度参数的配置,什么时候去做
  4. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。   你什么时候去做什么事?

w3cSchool上对Quarz的介绍:   https://www.w3cschool.cn/quartz_doc/

Quarz的官方文档:   http://www.quartz-scheduler.org/documentation/quartz-2.2.x/quick-start.html

二.如何使用Quarz?

(1) 在pom.xml中引入jar包

<!--quarz 任务调度-->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>

(2)  在需要调用Quarz加上代码

以下代码可以开启一个定时任务。

/**
 * 调用任务quarz管理器执行任务
 * @param userList
 * @param message
 * @param model
 */
private void createQuarzNews(Date date) throws SchedulerException {
    // 1、创建Job对象:你要做什么事?
    JobDetail jobDetail = JobBuilder.newJob(QuartzTask.class)   .withIdentity(String.valueOf(model.getId()),"myGrop").build();

    Trigger trigger = TriggerBuilder.newTrigger()
            .withSchedule(CronScheduleBuilder.cronSchedule(CronUtils.getCron(date)))
            .withIdentity(String.valueOf(model.getId()),"myGrop")
            .build();
    // 3.创建Scheduled对象,在什么时候做什么事?
    Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    scheduler.scheduleJob(jobDetail, trigger);
    // 启动
    scheduler.start();
}

(3)具体任务调度的实现类

package com.bos.quarz;

import com.bos.data.model.TemplateNewsModel;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * 任务调度的执行类
 *
 * @Author tanghh
 * @Date 2020/1/7 16:38
 */
public class QuartzTask implements Job {
  

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("quartz任务执行了...." + new Date());
        //可以在这里加上你的业务逻辑代码
        
    }
 
}


(4) 将当前时间转成cron表达式的方法。

package com.bos.quarz;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期转换cron表达式
 * @author Administrator
 *
 */
public class CronUtils {
    public static String formatDateByPattern(Date date,String dateFormat){
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String formatTimeStr = null;
        if (date != null) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }
    /***
     * convert Date to cron ,eg.  "0 07 10 15 1 ? 2016"
     * @param date  : 时间点
     * @return
     */
    public static String getCron(Date  date){
        String dateFormat="ss mm HH dd MM ? yyyy";
        return formatDateByPattern(date, dateFormat);
    }
}

(5)运行createQuarzNews ()这个方法就可以定时执行任务了

(6)介绍一下如何在开启Job的时候,如何往后面的类中传参

// 1、创建Job对象:你要做什么事?
JobDetail jobDetail = JobBuilder.newJob(QuartzTask.class) .withIdentity(String.valueOf(model.getId()),"myGrop").build();
//赋值参数
jobDetail.getJobDataMap().put("userList", userList);
jobDetail.getJobDataMap().put("message", message);

然后在 Quarz这个类中就可以获取这俩个参数

//获取传入的参数数据
JobDataMap data = jobExecutionContext.getJobDetail().getJobDataMap();
List userList = (List) data.get("userList");
String message = (String) data.get("message");

三.SpringBoot项目整合Quarz

(1)在pom.xml中引入依赖

<!--quarz 任务调度-->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 添加 Scheduled 坐标 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

(2) 添加Quarz的配置。

package com.test.quarz;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

/**
 * @Author tanghh
 * @Date 2020/1/9 11:41
 */
@Configuration
public class QuarzConfig {

    /**
     * 1.创建 Job 对象
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        //关联我们自己的 Job 类
        factory.setJobClass(QuartzTask.class);
        return factory;
    }

    /**
     * 2.创建 Trigger 对象
     * 简单的 Trigger
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
        SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
        //关联 JobDetail 对象
        factory.setJobDetail(jobDetailFactoryBean.getObject());
        //该参数表示一个执行的毫秒数
        factory.setRepeatInterval(2000);
        //重复次数
        factory.setRepeatCount(5);
        return factory;
    }


    /**
     * 设置任务的执行时间
     * @param jobDetailFactoryBean
     * @return
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
        factory.setJobDetail(jobDetailFactoryBean.getObject());
        //设置触发时间
        factory.setCronExpression("0 43 13 * * ? ");
        return factory;
    }

    /**
     * 3.创建 Scheduler 对象
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean) {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        //关联 trigger
        factory.setTriggers(cronTriggerFactoryBean.getObject());
        return factory;
    }
}

(3)编写具体需要实现的业务逻辑代码

package com.test.quarz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Date;

/**
 * @Author tanghh
 * @Date 2020/1/9 11:33
 */
public class QuartzTask implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("任务正在执行...." + new Date());
    }
}

(4)实现效果

四.最后感谢博主

其中有代码是参照下面这位博主来做的,有改动部分。感谢。

https://blog.csdn.net/qq_38526573/article/details/90401661

发布了46 篇原创文章 · 获赞 42 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tangthh123/article/details/103894783