springboot动态定时任务的实现方法示例
作者:qaqhat 发布时间:2023-04-20 15:59:58
标签:springboot,动态,定时任务
1、maven引入quartz包
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
2、创建定时任务工厂类
/**
* 定时任务工厂类
*/
@Component
public class JobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
final Object jobInstance = super.createJobInstance(bundle);
beanFactory.autowireBean(jobInstance);
return jobInstance;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
}
}
3、创建定时任务抽象类
public abstract class AbstractTask implements Job {
private Logger logger = LoggerFactory.getLogger(AbstractTask.class);
protected abstract void executeInternal(JobExecutionContext context) throws Exception;
/**
* 定时任务标识
*/
private String key;
/**
* 数据库里配置的主键id
*/
private Long dataBaseId;
@Override
public void execute(JobExecutionContext context) {
try {
executeInternal(context);
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.error("job execute failed!");
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Long getDataBaseId() {
return dataBaseId;
}
public void setDataBaseId(Long dataBaseId) {
this.dataBaseId = dataBaseId;
}
}
4、创建定时任务业务实现类
这里可以写你的业务代码,实现具体的业务逻辑。
@Component("JobTask")
public class JobTask extends AbstractTask {
@Override
protected void executeInternal(JobExecutionContext context) {
System.out.println("key = " + this.getKey());
System.out.println("dataBaseId = " + this.getDataBaseId());
}
}
5、创建定时任务管理器
包括项目启动时添加定时任务,手动添加定时任务,更新定时任务,删除定时任务方法。
/**
* 定时任务管理容器 component (单例模式)
*/
@Component
@Scope("singleton")
public class JobQuartzManager implements ApplicationContextAware {
/**
* 创建新的scheduler
*/
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
private Scheduler scheduler;
/**
* 定义组名称,不同的组用于区分任务
*/
private static final String JOB_GROUP_NAME = "JOB_GROUP_NAME";
private static final String TRIGGER_GROUP_NAME = "TRIGGER_GROUP_NAME";
/**
* 日志
*/
private Logger logger = LoggerFactory.getLogger(JobQuartzManager.class);
private ApplicationContext applicationContext;
@Autowired
private JobFactory jobFactory;
public void start() {
//启动定时任务(初始化)
try {
this.scheduler = schedulerFactory.getScheduler();
scheduler.setJobFactory(jobFactory); //设置定时任务工厂模式
//项目启动时默认给spring容器添加动态的定时任务
this.addJob("job" + 100L, 100L, JobTask.class, "0/2 * * * * ?");
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException("init Scheduler failed");
}
}
public boolean addJob(String jobName, Long dataBaseId, Class jobClass, String cronExp) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
logger.error("Illegal cron expression format({})", cronExp);
return result;
}
try {
JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, JOB_GROUP_NAME))
.ofType((Class<AbstractTask>) Class.forName(jobClass.getName()))
.build();
//创建完jobDetail之后,使用语句传参数值,方便定时任务内部识别它是什么标识
JobDataMap jobDataMap = jobDetail.getJobDataMap();
jobDataMap.put("key", jobName);
jobDataMap.put("dataBaseId", dataBaseId);
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName, TRIGGER_GROUP_NAME))
.build();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
result = true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.error("QuartzManager add job failed");
}
return result;
}
public boolean updateJob(String jobName, String cronExp) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
logger.error("Illegal cron expression format({})", cronExp);
return result;
}
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName, TRIGGER_GROUP_NAME))
.build();
scheduler.rescheduleJob(triggerKey, newTrigger);
result = true;
} else {
logger.error("update job name:{},group name:{} or trigger name:{},group name:{} not exists..",
jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
logger.error("update job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
}
return result;
}
public boolean deleteJob(String jobName) {
boolean result = false;
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey)) {
result = scheduler.deleteJob(jobKey);
} else {
logger.error("delete job name:{},group name:{} not exists.", jobKey.getName(), jobKey.getGroup());
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
logger.error("delete job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
}
return result;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
6、创建定时任务启动类
项目运行时给spring注入定时任务
/**
* 定时任务启动类
*/
@Component
public class JobRunner implements ApplicationRunner {
//注入定时任务管理器
@Autowired
private JobQuartzManager quartzManager;
/**
* 项目启动时激活定时任务
*/
@Override
public void run(ApplicationArguments applicationArguments) {
System.out.println("--------------------注入定时任务---------------------");
quartzManager.start();
System.out.println("--------------------定时任务注入完成---------------------");
}
}
7、测试案例
@RestController
@RequestMapping("/job")
public class JobController {
@Autowired
JobQuartzManager quartzManager;
@PostMapping("addJob")
@ResponseBody
public String addJob(@RequestParam("dataBaseId") Long dataBaseId, @RequestParam("cronExp") String cronExp){
boolean success = quartzManager.addJob("job" + dataBaseId, dataBaseId, JobTask.class, cronExp);
if(success){
return "添加成功";
}else{
return "添加失败!";
}
}
@PostMapping("deleteJob")
@ResponseBody
public String deleteJob(@RequestParam("jobName") String jobName){
boolean success = quartzManager.deleteJob(jobName);
if(success){
return "删除成功";
}else{
return "删除失败!";
}
}
@PostMapping("updateJob")
@ResponseBody
public String updateJob(@RequestParam("jobName") String jobName, @RequestParam("cronExp") String cronExp){
boolean success = quartzManager.updateJob(jobName, cronExp);
if(success){
return "更新成功";
}else{
return "更新失败!";
}
}
}
来源:https://blog.csdn.net/SSM1234/article/details/113607799


猜你喜欢
- 本文实例讲述了Android开发使用Handler的PostDelayed方法实现图片轮播功能。分享给大家供大家参考,具体如下:第一步:创建
- 引言 在c#中,可能大多数人针对于多线程之间的通讯,是熟能生巧,对于AsyncLocal 和Thre
- 效果图如下所述:布局<?xml version="1.0" encoding="utf-8"?
- 发现坑最近在配置项目主题的时候报了如下错误:This Activity already has an action bar supplied
- 星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。
- 在移动应用满天飞的时代,随着移动支付的盛行,很多应用中都集成了支付功能。之前的支付一直不是我负责,近期这个项目我负责订单模块少不了要做支付,
- 使用第三方json转换工具,阿里巴巴json转换工具Fastjson1.2.7。https://www.jb51.net/softs/530
- Usage扩展函数是 kotlin 的又一杀手锏功能,能够在不修改源码的基础上,扩展某些类的能力,方便开发。例如这里演示了给 String
- 编写按钮属性首先再values/themes 或者values/style在文件下编写按钮属性buttonBarPositiveButton
- 前言最近在改进项目的并发功能,但开发起来磕磕碰碰的。看了好多资料,总算加深了认识。于是打算配合查看源代码,总结并发编程的原理。准备从用得最多
- 上次写了一篇博文,但是每次更新图标时,桌面会闪烁(刷新)https://www.jb51.net/article/73350.htm,有博友
- JAVA 枚举单例模式及源码分析的实例详解 单例模式的实现有很多种,网上也分析了
- 本文实例讲述了WinForm实现的图片拖拽与缩放功能。分享给大家供大家参考,具体如下:最近做项目的时候遇到上传施工平面布置图,查看,因为图片
- 1、匿名内部类内部类:在一个类的内部定义了另外的类,称为内部类,匿名内部类指的是没有名字的内部类。为了清楚内部类的主要作用,下面首先观察一个
- 本文实例为大家分享了C语言实现稀疏矩阵的具体代码,供大家参考,具体内容如下#include "stdio.h"#defi
- 上标是指比同一行中其他文字稍高的文字,而下标是指比同一行中其他文字稍低的文字。在生活中,我们常见的平方米、立方米等符号以及化学中的各种元素符
- 概述HashTable是jdk 1.0中引入的产物,基本上现在很少使用了,但是会在面试中经常被问到,你都知道吗:HashTable底层的实现
- 本文实例讲述了JFreeChart插件实现的折线图效果。分享给大家供大家参考,具体如下:package com.lei.jfreechart
- using System;using System.Collections.Generic;using System.Linq;
- 本文实例为大家分享了java pdf加水印的具体代码,供大家参考,具体内容如下引入依赖<dependency> <grou