入门案例
参考链接:https://www.w3cschool.cn/quartz_doc/quartz_doc-1xbu2clr.html
引入依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
- Scheduler - 与调度程序交互的主要API。(关联并管理任务和触发器)
- Job - 你想要调度器执行的任务组件需要实现的接口(逻辑代码)
- JobDetail - 用于定义作业的实例。(可有多个实例)
- Trigger(即触发器) - 定义执行给定作业的计划的组件。(可有多个触发器,任务什么时间执行)
首先新建一个Job 类。
Job中可通过参数context获取 调度器、job实例、触发器 传递的参数
import java.time.LocalDateTime;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Object tv1 = context.getTrigger().getJobDataMap().get("t1");
Object tv2 = context.getTrigger().getJobDataMap().get("t2");
Object jv1 = context.getJobDetail().getJobDataMap().get("j1");
Object jv2 = context.getJobDetail().getJobDataMap().get("j2");
Object sv = null;
try {
sv = context.getScheduler().getContext().get("skey");
} catch (SchedulerException e) {
e.printStackTrace();
}
System.out.println(tv1+":"+tv2);
System.out.println(jv1+":"+jv2);
System.out.println(sv);
System.out.println("hello:"+ LocalDateTime.now());
}
}
在test类中新建调度器、job实例、触发器
可在调度器、job实例、触发器中传递参数
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
public class TestQuartz {
public static void main(String[] args) throws SchedulerException {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getContext().put("sKey", "sValue");
JobDetail job = JobBuilder.newJob(HelloJob.class)
.usingJobData("j1", "jv1")
.withIdentity("myJob", "myGroup").build();
job.getJobDataMap().put("j2", "jv2");
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.usingJobData("t1", "tv1")
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3)
.repeatForever()).build();
trigger.getJobDataMap().put("t2", "tv2");
scheduler.scheduleJob(job, trigger);
scheduler.start();
}
}
Spring Boot整合Quartz-持久化到数据库
参考链接:
https://www.cnblogs.com/sxxs/p/13383929.html
https://blog.csdn.net/qq_45337977/article/details/122890488
引入依赖 添加配置文件quartz.properties (官网默认配置文件在org.quartz包下)
# 主配置
org.quartz.scheduler.instanceName=MyScheduler
org.quartz.scheduler.skipUpdateCheck=true
# ThreadPool配置
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#最多有25个任务同时在执行,如果有第26个任务将会被搁置
org.quartz.threadPool.threadCount=25
org.quartz.threadPool.threadPriority=5
# JobStoreTx配置
#第一个任务的执行完后的结束时间 减去 第二个任务的开始时间 = 时间间隔,时间间隔 大于 60s时, 第二个任务不会被执行。
#这个叫做失败临界值,或者临界时间
org.quartz.jobStore.misfireThreshold=6000
#存储方式使用JobStoreTX,也就是数据库
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
#指示JDBCJobStore,JobDataMaps中的所有值都将是“字符串”,因此可以将其存储为key-value键值对,而不是以BLOB列的序列化形式存储更复杂的对象。
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.dataSource=myDS
#数据库中quartz表的表名前缀
org.quartz.jobStore.tablePrefix=qrtz_
#是否使用集群(如果项目只部署到 一台服务器,就不用了)
org.quartz.jobStore.isClustered=false
#修改连接池(Quartz默认为c3p0连接池)
org.quartz.dataSource.myDS.provider=hikaricp
org.quartz.dataSource.myDS.driver=org.postgresql.Driver
org.quartz.dataSource.myDS.URL=jdbc:postgresql://localhost:5432/dtmg?useUnicode=true&characterEncoding=utf8&autoReconnect=true&stringtype=unspecified
org.quartz.dataSource.myDS.user=postgres
org.quartz.dataSource.myDS.password=Password
#最大连接数
org.quartz.dataSource.myDS.maxConnections=50
在数据库中执行对应数据库 sql 文件
数据库语句:org.quartz.impl.jdbcjobstore 包下
配置-JobFactory
由于可能要在job里注入spring对象,不做配置,是无法注入的。
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class JobFactory extends SpringBeanJobFactory {
@Resource
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
创建quartz的配置文件
import org.quartz.Scheduler;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Properties;
@Configuration
public class QuartzConfig {
@Resource
private JobFactory jobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
try {
schedulerFactoryBean.setJobFactory(jobFactory);
schedulerFactoryBean.setOverwriteExistingJobs(true);
schedulerFactoryBean.setStartupDelay(10);
schedulerFactoryBean.setQuartzProperties(quartzProperties());
} catch (IOException e) {
e.printStackTrace();
}
return schedulerFactoryBean;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
封装定时任务的启动、修改、删除的一些工具
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
@Component
@Slf4j
public class QuartzJobManager {
private static QuartzJobManager jobUtil;
@Resource
private Scheduler scheduler;
public QuartzJobManager() {
log.info("init jobUtil");
jobUtil = this;
}
public static QuartzJobManager getInstance() {
log.info("return JobCreateUtil");
return QuartzJobManager.jobUtil;
}
public void addJob(Class jobClass, String jobName, String jobGroupName, String cronExpression) throws Exception {
addJob(jobClass, jobName, jobGroupName, cronExpression, null);
}
public void addJob(Class jobClass, String jobName, String jobGroupName, String cronExpression, Map<String, Object> argMap) throws Exception {
try {
deleteJob(jobName, jobGroupName);
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withIdentity(jobName, jobGroupName)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobGroupName)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
.build();
if (argMap != null) {
trigger.getJobDataMap().putAll(argMap);
}
scheduler.scheduleJob(jobDetail, trigger);
if (scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
log.error(jobName + ":加入定时任务失败");
throw new Exception("加入定时任务失败");
}
}
public void pauseJob(String jobName, String jobGroupName) {
try {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public void resumeJob(String jobName, String jobGroupName) {
try {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public void updateJob(String jobName, String jobGroupName, String cronExpression) {
updateJob(jobName, jobGroupName, cronExpression, null);
}
public void updateJob(String jobName, String jobGroupName, String cronExpression, Map<String, Object> argMap) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
if (argMap != null) {
trigger.getJobDataMap().putAll(argMap);
}
scheduler.rescheduleJob(triggerKey, trigger);
} catch (Exception e) {
e.printStackTrace();
}
}
public void updateJob(String jobName, String jobGroupName, Map<String, Object> argMap) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
trigger.getJobDataMap().putAll(argMap);
scheduler.rescheduleJob(triggerKey, trigger);
} catch (Exception e) {
e.printStackTrace();
}
}
public void deleteJob(String jobName, String jobGroupName) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
if (triggerKey != null) {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void startAllJobs() {
try {
scheduler.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void shutdownAllJobs() {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public List<Map<String, Object>> getAllJob() {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
List<Map<String, Object>> jobList = new ArrayList<>();
Set<JobKey> jobKeys;
try {
jobKeys = scheduler.getJobKeys(matcher);
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
Map<String, Object> job = new HashMap<>(16, 0.75f);
job.put("jobName", jobKey.getName());
job.put("jobGroupName", jobKey.getGroup());
job.put("trigger", trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.put("cronExpression", cronExpression);
}
jobList.add(job);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}
public Map<String, Object> getJobInfo(String jobName, String jobGroupName) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
Map<String, Object> job = new HashMap<>(16, 0.75f);
try {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (trigger == null) {
return job;
}
job.put("jobName", jobName);
job.put("jobGroupName", jobGroupName);
job.put("trigger", trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.put("jobStatus", triggerState.name());
String cronExpression = trigger.getCronExpression();
job.put("cronExpression", cronExpression);
} catch (SchedulerException e) {
e.printStackTrace();
}
return job;
}
public boolean flagJob(String jobName, String jobGroupName) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
try {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (trigger == null) {
return false;
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return true;
}
}
根据自己需求创建自己的Job
import com.codvision.serverboot.service.XXXXService;
import lombok.SneakyThrows;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class XXXXJob implements Job {
@Resource
private XXXXService xxxxService;
@SneakyThrows
@Override
public void execute(JobExecutionContext jobExecutionContext) {
JobDataMap jobDataMap = jobExecutionContext.getTrigger().getJobDataMap();
int taskId = Integer.parseInt(jobDataMap.get("xxxId").toString());
xxxxService.updateXXXX(xxxId);
}
}
业务层根据自己需求,对任务进行操作
@Slf4j
@Service
public class XXXXService{
@Resource
private QuartzJobManager quartzJobManager;
// 方法中调用quartzJobManager对应方法即可
}
如需求比较简单,也可不创建QuartzJobManager ,直接创建对应的job实例、触发器工具类。
|