Quartz定时任务

Quartz是OpenSymphony开源组织在Jobscheduling领域又一个开源项目,完全用Java开发,用于执行预定任务。它类似于java.util.Timer定时器,但是它又比Timer多很多功能。

简单定时任务(内存持久化)

首先引入maven依赖:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>1234复制代码类型:[java]

定义一个接口实现计时功能(例如:定时发送邮件、提醒消息、...):

创建定时任务类QSimpleTask继承QuzrtzJobBean:

package com.example.demo.task;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.scheduling.quartz.QuartzJobBean;import java.util.Date;public class QSimpleTask extends QuartzJobBean { @Override
 protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  System.out.println("简单的定时任务执行时间:" + new Date().toLocaleString());
 }
}1234567891011121314复制代码类型:[java]

我们还需要编写一个配置类做触发任务执行的触发器(指定任务的运行时间、执行时间、执行间隔)

package com.example.demo.config;import com.example.demo.task.QSimpleTask;import org.quartz.*;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class QSimpleConfig { // 指定具体的定时任务类
 @Bean
 public JobDetail uploadTaskDetail() {  return JobBuilder.newJob(QSimpleTask.class)
 .withIdentity("QSimpleTask")
 .storeDurably().build();
 } @Bean
 public Trigger uploadTaskTrigger() {  // 设定触发执行的方式,定时任务,每隔7秒执行一次
  CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/7 * * * * ?");  // 返回任务触发器
  return TriggerBuilder.newTrigger().forJob(uploadTaskDetail())
 .withIdentity("QSimpleTask")
 .withSchedule(scheduleBuilder)
 .build();
 }
}12345678910111213141516171819202122232425262728复制代码类型:[java]

之后实现Job这个简单的接口:

package com.example.demo.job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public interface Job { // 提供上下文调度信息
 void execute(JobExecutionContext context) throws JobExecutionException;
}123456789复制代码类型:[java]

运行代码,得到结果:

动态定时任务(数据库持久化)

有些定时任务执行一段时间以后就不需要了,如果在代码中进行修改然后重新打包发布,Quartz可以解决这个问题。

我们将使用Quartz提供的API完成配置任务的增删改查,将任务的配置保存在数据库中。

在application.yml文件中进行配置:

spring:
  datasource:
   url: jdbc:mysql://localhost:3306/Family?useUnicode=true&characterEncoding=utf-8&useSSL=false
   username: root
   password: 123456
   driver-class-name: com.mysql.cj.jdbc.Driver
  quartz:
 # 数据库存储quartz任务配置 job-store-type: JDBC
 jdbc:
   # 自动初始化表结构,第一次启动的时候这里写always,之后改成NEVER
   initialize-schema: always 123456789101112复制代码类型:[java]

创建一个定时相关的实体类并保存到数据库中去:

package com.example.demo.model;import lombok.Data;@Datapublic class QBean { // 任务id
 private String id; // 任务名称
 private String jobName; // 任务执行类
 private String jobClass; // 任务状态
 private Integer status; // 任务运行时间表达式
 private String cronExpression;
}123456789101112131415161718192021复制代码类型:[java]

在util文件夹下创建定时任务暂停,修改,启动,单次启动工具类:

package com.example.demo.utils;import com.example.demo.model.QBean;import org.quartz.*;public class QUtils { @SuppressWarnings("unchecked")
 public static void createScheduleJob(Scheduler scheduler, QBean quartzBean) throws ClassNotFoundException, SchedulerException {  // 获取到定时任务的执行类
  // 定时任务类需要是job类的具体实现 QuartzJobBean是job的抽象类
  Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());  // 构建定时任务信息
  JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(quartzBean.getJobName()).build();  // 设置定时任务执行方式
  CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());  // 构建触发器
  CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(quartzBean.getJobName()).withSchedule(scheduleBuilder).build();
  scheduler.scheduleJob(jobDetail, trigger);
 } public static void pauseScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(jobName);
  scheduler.pauseJob(jobKey);
 } public static void resumeScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(jobName);
  scheduler.resumeJob(jobKey);
 } public static void runOnce(Scheduler scheduler, String jobName) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(jobName);
  scheduler.triggerJob(jobKey);
 } public static void updateScheduleJob(Scheduler scheduler, QBean quartzBean) throws SchedulerException {  // 获取到对应任务的触发器
  TriggerKey triggerKey = TriggerKey.triggerKey(quartzBean.getJobName());  // 设置定时任务执行方式
  CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());  // 重新构建任务的触发器
  CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();  // 重置对应的job
  scheduler.rescheduleJob(triggerKey, trigger);
 } public static void deleteScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(jobName);
  scheduler.deleteJob(jobKey);
 }
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253复制代码类型:[java]

最后再编写controller代码:

package com.example.demo.controller;import com.example.demo.model.QBean;import com.example.demo.utils.QUtils;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;@Controller@RequestMapping("/QZ/job/")public class QController { // 注入scheduler
 @Resource
 private Scheduler scheduler; @PostMapping("/create")
 @ResponseBody
 public String createJob(@RequestBody QBean quartzBean) throws SchedulerException, ClassNotFoundException {
  QUtils.createScheduleJob(scheduler, quartzBean);  return "创建任务成功";
 } @PostMapping("/pause")
 @ResponseBody
 public String pauseJob(String jobName) throws SchedulerException {
  QUtils.pauseScheduleJob(scheduler, jobName);  return "暂停";
 } @PostMapping("/run")
 @ResponseBody
 public String runOnce(String jobName) throws SchedulerException {
  QUtils.runOnce(scheduler, jobName);  return "运行" + jobName + "成功";//这里return不是生产级别代码,测试简单写一下
 } @PostMapping("/resume")
 @ResponseBody
 public String resume(String jobName) throws SchedulerException {
  QUtils.resumeScheduleJob(scheduler, jobName);  return "恢复定时任务成功:" + jobName;
 } @PostMapping("/update")
 @ResponseBody
 public String update(@RequestBody QBean quartzBean) throws SchedulerException {
  QUtils.updateScheduleJob(scheduler, quartzBean);  return "更新定时任务调度信息成功";
 }
}
(0)

相关推荐