springboot 框架 +quartz 动态定时器 单表
前言
项目中 需要集合 quartz 定时器,本篇文章 底层框架为springboot +quartz,任务会写入到数据库
提示:以下是本篇文章正文内容,下面案例可供参考
一、建立定时任务表 和导入依赖
表
示例:
CREATE TABLE `sys_quartz_task` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`class_name` varchar(255) NOT NULL COMMENT '全类名,反射用',
`cron` varchar(255) NOT NULL COMMENT '表达式',
`job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '任务名称',
`job_group_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务组名,相同任务分组一般不同',
`trigger_name` varchar(255) NOT NULL COMMENT '调度名',
`trigger_group_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '调度分组',
`status` int NOT NULL DEFAULT '1' COMMENT '状态 0 取消执行 1 执行',
`described` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3;
导入依赖
<!--定时任务 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
二、代码
quartz 配置
代码如下(示例):可建可不建这个类,有默认实现
@Configuration
public class QuartzFactoryBean implements SchedulerFactoryBeanCustomizer {
@Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setStartupDelay(10);
schedulerFactoryBean.setOverwriteExistingJobs(true);
}
}
ApplicationRunnerImpl 启动容器执行的类
代码如下:这个是应用启动时,会执行该方法,从而启动所有的定时任务
@Component
public class ApplicationRunnerImpl implements ApplicationRunner {
@Autowired
private SysQuartzTaskDao sysQuartzTaskDao;
@Override
public void run(ApplicationArguments args){
SysQuartzTask tasks = new SysQuartzTask();
List<SysQuartzTask> tasksList = sysQuartzTaskDao.selectList(
new QueryWrapper<SysQuartzTask>().eq("status",1));
tasksList.forEach(item->{
try {
QuartzManager.addJob(item.getJobName(),item.getJobGroupName(),item.getTriggerName(),
item.getTriggerGroupName(),Class.forName(item.getClassName()),item.getCron());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
});
}
}
任务类
代码如下:任务类,将这个类的全类名写入到数据库
/*
@Author
*@Description DisallowConcurrentExecution不允许并发执行
**/
@DisallowConcurrentExecution
public class TestJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("test quartz");
}
}
定时任务工具类
代码如下: 定时任务调用的工具类
public class QuartzManager {
//应用启动后,Scheduler已经装配到ioc容器中了,无需重新new一个
private static Scheduler scheduler = SpringContextUtils.getBean(Scheduler.class);
public static void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, Class jobClass, String cron) {
try {
// 任务名,任务组,任务执行类
JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置JobDetail和Trigger
scheduler.scheduleJob(jobDetail, trigger);
// 启动 shutdown 停止的意思
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 新增 定时任务
*/
public static void addJob(String jName, String jGroup, String tName, String tGroup, String cron ,String className) {
try {
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(className))
.withIdentity(jName, jGroup)
.build();
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(tName, tGroup)
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
scheduler.start();
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 暂停定时任务
*/
public static void pauseJob (String jName, String jGroup ) {
try {
scheduler.pauseJob(JobKey.jobKey(jName, jGroup));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 继续定时任务
* @param jName
* @param jGroup
*/
public static void resumeJob(String jName, String jGroup) {
try {
scheduler.resumeJob(JobKey.jobKey(jName, jGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 删除定时任务
* @param jName
* @param jGroup
*/
public static void deleteJob(String jName, String jGroup) {
try {
JobKey jobKey = new JobKey(jName, jGroup);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null) {
return;
}
scheduler.deleteJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复所有任务
*
* @throws SchedulerException
*/
public static void resumeAllJob() throws SchedulerException {
scheduler.resumeAll();
}
/**
* 暂停所有任务
*
* @throws SchedulerException
*/
public static void pauseAllJob() throws SchedulerException {
scheduler.pauseAll();
}
/**
* 修改某个任务的执行时间
*
* @param name 任务名称
* @param group 任务分组
* @param time 时间表达式
* @return
* @throws SchedulerException
*/
public static 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;
}
/**
* 获取Job信息
*
* @param name 任务名称
* @param group 任务分组
* @return
* @throws SchedulerException
*/
public static 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());
}
}
通过name获取bean 的工具类
代码如下(示例):工具类,通过name获取bean
@Component
public class SpringContextUtils implements ApplicationContextAware {
/**
* 上下文对象实例
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 获取applicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
controller 测试使用
controller 接口,测试用
@Api(tags = "定时器")
@RestController
@RequestMapping("quartz")
public class QuartzController {
@PostMapping("create")
@Operation(summary = "定时任务-新增")
public ResponseData<?> create() throws IOException {
return ResponseData.buildSuccess();
}
@RequestMapping("/start")
@ResponseBody
public String startQuartzJob() {
try {
// QuartzManager.startJob();
} catch (Exception e) {
e.printStackTrace();
return "false";
}
return "success";
}
@RequestMapping("/info")
@ResponseBody
public String getQuartzJob(@RequestParam String name, @RequestParam String group) {
String info = null;
try {
info = QuartzManager.getJobInfo(name, group);
} catch (SchedulerException e) {
e.printStackTrace();
}
return info;
}
@RequestMapping("/modify")
@ResponseBody
public boolean modifyQuartzJob(@RequestParam String name,@RequestParam String group,@RequestParam String time) {
boolean flag = true;
try {
flag = QuartzManager.modifyJob(name, group, time);
} catch (SchedulerException e) {
e.printStackTrace();
}
return flag;
}
@RequestMapping(value = "/pause")
@ResponseBody
public String pauseQuartzJob(@RequestParam String name,@RequestParam String group) {
try {
QuartzManager.pauseJob(name, group);
} catch (Exception e) {
e.printStackTrace();
return "false";
}
return "success";
}
@RequestMapping(value = "/pauseAll")
@ResponseBody
public String pauseAllQuartzJob() {
try {
QuartzManager.pauseAllJob();
} catch (SchedulerException e) {
e.printStackTrace();
return "false";
}
return "success";
}
@RequestMapping(value = "/delete")
@ResponseBody
public String deleteJob(@RequestParam String name,@RequestParam String group) {
try {
QuartzManager.deleteJob(name, group);
} catch (Exception e) {
e.printStackTrace();
return "false";
}
return "success";
}
}
如果是多实例部署,一定记得加分布式锁
-
java
-
quartz
-
Springboot
-
工具使用
好评