前言:
今天主要简单的讲一下Quarz任务框架的使用。
现在有个需求,需要做一个提醒功能,相当于一个闹钟功能,举个例子:5点处理企业微信上未读消息,6点对数据进行备份。
一般情况下定时定点的定时任务直接用@Schedule ,也可以用Timer ,给Timer设置时间,存在缺陷,通过同时执行俩个任务的话,如果第一个任务报错了,那么第二个任务就直接挂掉了。 这么一分析的话,我就想到了用Quarz ,因为它的任务是动态的,我只需要管理这些任务。以下俩种方式都可实现,第一种方式更加灵活,灵活设置执行时间,第二种是与Spingboot的结合。
一.介绍Quarz
几个核心的点:
- Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下: 你要做什么事?
void execute(JobExecutionContext context)
- JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
- Trigger 代表一个调度参数的配置,什么时候去做。
- 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)实现效果
四.最后感谢博主
其中有代码是参照下面这位博主来做的,有改动部分。感谢。