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)