一、Quartz 简介
- Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。
- Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。
- Quartz 允许程序开发人员根据时间的间隔来调度作业。
- Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。
二、Quartz 核心概念
- Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:void execute(JobExecutionContext context)
- JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
- Trigger 代表一个调度参数的配置,什么时候去调。
- Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。
三、代码
1、引入 pom.xml 相关依赖
<!--quartz定时任务-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
2、任务调度处理
package com.huapu.eng.plat.quartz;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.util.Date;
/**
* @ClassName QuartzScheduler
* @Description 任务调度处理
* @Author liulianjia
* @Date 17:11 2022/5/30
* @Version 1.0
**/
@Configuration
public class SchedulerQuartz {
/**
* @author liulianjia
* @Description 任务调度
* @date 2022/5/30 17:14
* @param
**/
@Autowired
private Scheduler scheduler;
/**
* 开始执行所有任务
*
* @throws SchedulerException
*/
public void startJob() throws SchedulerException {
startJob(scheduler);
scheduler.start();
}
/**
* 获取Job信息
*
* @param name
* @param group
* @return
* @throws SchedulerException
*/
public String getJobInfo(String name, String group) throws SchedulerException {
TriggerKey triggerKey = new TriggerKey(name, group);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),
scheduler.getTriggerState(triggerKey).name());
}
/**
* 修改某个任务的执行时间
*
* @param name
* @param group
* @param time
* @return
* @throws SchedulerException
*/
public boolean modifyJob(String name, String group, String time) throws SchedulerException {
Date date = null;
TriggerKey triggerKey = new TriggerKey(name, group);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
String oldTime = cronTrigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
.withSchedule(cronScheduleBuilder).build();
date = scheduler.rescheduleJob(triggerKey, trigger);
}
return date != null;
}
/**
* 暂停所有任务
*
* @throws SchedulerException
*/
public void pauseAllJob() throws SchedulerException {
scheduler.pauseAll();
}
/**
* 暂停某个任务
*
* @param name
* @param group
* @throws SchedulerException
*/
public void pauseJob(String name, String group) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null) {
return;
}
scheduler.pauseJob(jobKey);
}
/**
* 恢复所有任务
*
* @throws SchedulerException
*/
public void resumeAllJob() throws SchedulerException {
scheduler.resumeAll();
}
/**
* 恢复某个任务
*
* @param name
* @param group
* @throws SchedulerException
*/
public void resumeJob(String name, String group) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null) {
return;
}
scheduler.resumeJob(jobKey);
}
/**
* 删除某个任务
*
* @param name
* @param group
* @throws SchedulerException
*/
public void deleteJob(String name, String group) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null) {
return;
}
scheduler.deleteJob(jobKey);
}
private void startJob(Scheduler scheduler) throws SchedulerException {
// 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
// JobDetail 是具体Job实例
JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob.class).withIdentity("refreshAccessToken", "group").build();
// 基于表达式构建触发器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 0/2 * * ?");
// CronTrigger表达式触发器 继承于Trigger
// TriggerBuilder 用于构建触发器实例
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("refreshAccessToken", "group")
.withSchedule(cronScheduleBuilder).build();
scheduler.scheduleJob(jobDetail, cronTrigger);
}
}
3、Scheduler注入(采用监听spring容器加载完毕后事件, 启动任务调用)
package com.huapu.eng.plat.quartz;
import com.huapu.eng.plat.util.WxAccountUtils;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
/**
* @ClassName ApplicationStartQuartzJobListener
* @Description Scheduler注入(采用监听spring容器加载完毕后事件, 启动任务调用)
* @Author liulianjia
* @Date 17:15 2022/5/30
* @Version 1.0
**/
@Configuration
public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private SchedulerQuartz schedulerQuartz;
/**
* 初始启动quartz
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
try {
schedulerQuartz.startJob();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始注入scheduler
* @return
* @throws SchedulerException
*/
@Bean
public Scheduler scheduler() throws SchedulerException{
SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();
return schedulerFactoryBean.getScheduler();
}
}
4、业务代码
package com.huapu.eng.plat.quartz;
import com.huapu.eng.plat.util.WxAccountUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @ClassName SchedulerQuartzJob1
* @Description 业务代码
* @Author liulianjia
* @Date 17:19 2022/5/30
* @Version 1.0
**/
public class SchedulerQuartzJob implements Job {
private final Logger logger = LoggerFactory.getLogger(SchedulerQuartzJob.class);
private void before(){
logger.info("----------任务开始执行, 开始时间 {}----------", System.currentTimeMillis());
}
@Override
public void execute(JobExecutionContext arg0) {
before();
// TODO 业务代码
after();
}
private void after(){
logger.info("----------任务结束执行, 结束时间 {}----------", System.currentTimeMillis());
}
}
5、测试
/**
* @author liulianjia
* @Description 动态刷新定时任务
* @date 2022/6/1 14:17
* @param
**/
public void modifyJon() throws SchedulerException {
Calendar nowTime = Calendar.getInstance();
nowTime.add(Calendar.MINUTE, 115);
//获取小时
int hour = nowTime.get(Calendar.HOUR_OF_DAY);
//获取分钟
int minutes = nowTime.get(Calendar.MINUTE);
//拼接cron表达式
String cron = "0 " + minutes + " " + hour + " * * ?";
logger.info("----------下次执行任务时间:{}", cron);
schedulerQuartz.modifyJob("refreshAccessToken", "group", cron);
}
6、cron表达式