SpringBoot整合quartz实现动态启动,停止定时任务功能
注意:这个方法当程序重启之后会失效,所以必须将定时任务持久化到数据库,然后程序启动的时候重新把数据库的定时任务加载到quartz中
springboot程序启动初始化代码参考:https://www.cnblogs.com/pxblog/p/14995261.html
引入maven
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
TaskJob.java 任务执行类
import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; /** * @PersistJobDataAfterExecution 和 @DisallowConcurrentExecution * 表示不让某个定时任务并发执行保证上一个任务执行完后,再去执行下一个任务 */ @PersistJobDataAfterExecution @DisallowConcurrentExecution @Component public class TaskJob implements Job { /** * 可以直接注入service层。这里只是演示,没有这个类 */ @Autowired private TaskService taskService; @Override public void execute(JobExecutionContext context) { JobDataMap jobDataMap=context.getJobDetail().getJobDataMap(); System.out.println("11"+new Date()+" "+jobDataMap.getString("value")+" "+context.getJobDetail().getKey()); } }
控制器
TaskController.java
import com.test.cms.task.TaskJob; import org.quartz.JobDataMap; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.*; @RestController public class TaskController { /** * 启动任务 需要自己完善逻辑,这里我用uuid作为taskCode 保证唯一 * 启动之前要通过数据库查询是否任务已经启动,如果启动了就不能启动了 * 启动成功了 要把数据库的任务状态改为启动中 */ @RequestMapping(value = "/task/start") public void start() { String uuid = UUID.randomUUID().toString(); System.out.println(uuid); startTask(uuid); } /** * 停止任务 需要自己完善逻辑 * @param taskCode 传入启动任务时设置的taskCode参数 */ @RequestMapping(value = "/task/stop") public void stop(String taskCode) { endTask(taskCode); } /** * 开始任务调度 * * @param taskCode 任务名称 需要唯一标识,停止任务时需要用到 */ private void startTask(String taskCode){ //任务开始的corn表达式 String cronExpress = "*/5 * * * * ?"; if (cronExpress.indexOf("null") == -1) { try { JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean(); jobDetailFactoryBean.setName(taskCode); jobDetailFactoryBean.setGroup(Scheduler.DEFAULT_GROUP); //TaskJob.class 是任务所要执行操作的类 jobDetailFactoryBean.setJobClass(TaskJob.class); //任务需要的参数可以通过map方法传递, Map map = new HashMap(); map.put("value", "我在传递参数"); jobDetailFactoryBean.setJobDataMap(getJobDataMap(map)); jobDetailFactoryBean.afterPropertiesSet(); CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setBeanName(taskCode); cronTriggerFactoryBean.setCronExpression(cronExpress); cronTriggerFactoryBean.setGroup(Scheduler.DEFAULT_GROUP); cronTriggerFactoryBean.setName("cron_" + taskCode); cronTriggerFactoryBean.afterPropertiesSet(); scheduler.scheduleJob(jobDetailFactoryBean.getObject(), cronTriggerFactoryBean.getObject()); System.out.println(taskCode+"任务启动成功"); } catch (Exception e) { e.printStackTrace(); System.out.println(taskCode+"任务启动失败"); } } } /** * 结束任务调度 * * @param taskCode */ private void endTask(String taskCode) { try { scheduler.deleteJob(JobKey.jobKey(taskCode, Scheduler.DEFAULT_GROUP)); System.out.println(taskCode+"任务停止成功"); } catch (SchedulerException e) { e.printStackTrace(); System.out.println(taskCode+"任务停止失败"); } } /** * 将HashMap转为JobDataMap * @param params * @return */ private JobDataMap getJobDataMap(Map<String, String> params) { JobDataMap jdm = new JobDataMap(); Set<String> keySet = params.keySet(); Iterator<String> it = keySet.iterator(); while (it.hasNext()) { String key = it.next(); jdm.put(key, params.get(key)); } return jdm; } @Autowired private Scheduler scheduler; }
启动类要加上注解@EnableScheduling
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling //要加上开启定时任务的注解 public class CmsApplication { public static void main(String[] args) { SpringApplication.run(CmsApplication.class, args); } }
JAVA日期Date格式转corn表达式:https://www.cnblogs.com/pxblog/p/14992923.html
-----------------------有任何问题可以在评论区评论,也可以私信我,我看到的话会进行回复,欢迎大家指教------------------------
(蓝奏云官网有些地址失效了,需要把请求地址lanzous改成lanzoux才可以)
分类:
JAVA
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了