1、引入quartz

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>

2、配置quartz运行在数据库中,application.properties中添加

spring.quartz.job-store-type=jdbc//默认是运行在MEMORY中

spring.quartz.jdbc.initialize-schema=always//每次启动都初始化数据库,3种模式(ALWAYS、EMBEDDED、NEVER)

其余要配置的属性spring boot提供Map<String, String> properties,你可以设置其他quartz的property.

spring.quartz.properties.*=proertyValue

例如设置driverDelegateClass属性,application.properties中

spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

3、demo

一个简单的demo,TestQuartz继承QuartzJobBean,Spring中的TestService注入到TestQuartz中(spring boot2.0自动配置实现),如果是spring boot1.*则需要自定义实现spring的bean添加到quartz的上下文中,否则会报空指针。

spring boot 1.*+quartz整合详见上一篇文章。

https://blog.csdn.net/jieyanqulaopo123/article/details/79983917

部分代码:

TestQuartzTrigger .java

package com.example.demo.quartz;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class TestQuartzTrigger implements ApplicationRunner {

private final static Logger LOGGER = LogManager.getLogger(TestQuartzTrigger.class);
@Autowired
QuartzManager quartzManager;
@Override
public void run(ApplicationArguments args){
// TODO Auto-generated method stub
LOGGER.info(“启动测试testQuartz”);
try {
//20秒执行一次
quartzManager.addOrUpdateJob(TestQuartz.class, “testQuartz”, “testQuartz”, “0/20 * * * * ? *”);
} catch (Exception e) {
// TODO Auto-generated catch block
LOGGER.error(“启动测试testQuartz异常、异常信息:{}”,e.getMessage());
e.printStackTrace();
}
}

}

TestQuartz.java

package com.example.demo.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class TestQuartz extends QuartzJobBean{

@Autowired
TestService testService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
testService.service1();
}

}

TestService.java

package com.example.demo.quartz;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
@Service
public class TestService {
private final static Logger LOGGER = LogManager.getLogger(TestService.class);
public void service1(){
LOGGER.info(“test service1”);
}

}

QuartzManager.java任务常用操作类

package com.example.demo.quartz;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * quartz管理类
 * 
 * @author Danger
 *
 */
@Service
public class QuartzManager {
@Autowired
private Scheduler sched;

/**
* 增加一个job

* @param jobClass
*            任务实现类
* @param jobName
*            任务名称
* @param jobGroupName
*            任务组名
* @param jobCron
*            cron表达式(如:0/5 * * * * ? )
*/
public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, String jobCron) {
try {
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(jobCron)).startNow().build();

sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start();
}
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/**
* 创建or更新任务,存在则更新不存在创建

* @param jobClass
*            任务类
* @param jobName
*            任务名称
* @param jobGroupName
*            任务组名称
* @param jobCron
*            cron表达式
*/
public void addOrUpdateJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, String jobCron) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
addJob(jobClass, jobName, jobGroupName, jobCron);
} else {
if(trigger.getCronExpression().equals(jobCron)){
return;
}
updateJob(jobName, jobGroupName, jobCron);
}
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**

* @param jobClass
* @param jobName
* @param jobGroupName
* @param jobTime
*/
public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, int jobTime) {
addJob(jobClass, jobName, jobGroupName, jobTime, -1);
}

public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, int jobTime, int jobTimes) {
try {
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任务名称和组构成任务key
.build();
// 使用simpleTrigger规则
Trigger trigger = null;
if (jobTimes < 0) {
trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
.startNow().build();
} else {
trigger = TriggerBuilder
.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
.startNow().build();
}
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}

public void updateJob(String jobName, String jobGroupName, String jobTime) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
// 重启触发器
sched.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}

/**
* 删除任务一个job

* @param jobName
*            任务名称
* @param jobGroupName
*            任务组名
*/
public void deleteJob(String jobName, String jobGroupName) {
try {
sched.deleteJob(new JobKey(jobName, jobGroupName));
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 暂停一个job

* @param jobName
* @param jobGroupName
*/
public void pauseJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
sched.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}

/**
* 恢复一个job

* @param jobName
* @param jobGroupName
*/
public void resumeJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
sched.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}

/**
* 立即执行一个job

* @param jobName
* @param jobGroupName
*/
public void runAJobNow(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
sched.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}

/**
* 获取所有计划中的任务列表

* @return
*/
public List<Map<String, Object>> queryAllJob() {
List<Map<String, Object>> jobList = null;
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = sched.getJobKeys(matcher);
jobList = new ArrayList<Map<String, Object>>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = sched.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
Map<String, Object> map = new HashMap<>();
map.put(“jobName”, jobKey.getName());
map.put(“jobGroupName”, jobKey.getGroup());
map.put(“description”, “触发器:” + trigger.getKey());
Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
map.put(“jobStatus”, triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put(“jobTime”, cronExpression);
}
jobList.add(map);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}

/**
* 获取所有正在运行的job

* @return
*/
public List<Map<String, Object>> queryRunJon() {
List<Map<String, Object>> jobList = null;
try {
List<JobExecutionContext> executingJobs = sched.getCurrentlyExecutingJobs();
jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
Map<String, Object> map = new HashMap<String, Object>();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
map.put(“jobName”, jobKey.getName());
map.put(“jobGroupName”, jobKey.getGroup());
map.put(“description”, “触发器:” + trigger.getKey());
Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
map.put(“jobStatus”, triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put(“jobTime”, cronExpression);
}
jobList.add(map);
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}

}

4、总结

spring boot2整合了quartz,使定时执行非常简单了。

本例中使用的是postgresql数据据,quartz的driverDelegateClass必须设置为:

org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

默认为通用实现:org.quartz.impl.jdbcjobstore.StdJDBCDelegate

疑问:

设置了spring.quartz.jdbc.initialize-schema=always程序启动会自动quartz相关表,我测试用的是postgresql数据库,自动创建会缺少表,创建表的sql是quartz2.3.0.jar的org.quartz.impl.jdbcjobstore.tables_postgresql.sql,发现

DROP TABLE IF EXISTS  qrtz_fired_trigger`s;这句,认为是多`

用winwar打开jar把’去掉了,程序启动还是报错,错误信息为找不到 ***表,不知道为什么?

错误信息:

Caused by: org.postgresql.util.PSQLException: 错误: 关系 “qrtz_triggers” 不存在

去掉了到是可以在客户端工具中执行了。。。

可以手工执行sql创建表,然后注释掉

#spring.quartz.jdbc.initialize-schema=always

完。


版权声明:本文为jieyanqulaopo123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/jieyanqulaopo123/article/details/79991781