欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

springboot整合quartz实现数据库动态配置

时间:2023-07-02
什么是Quzrtz?

Quartz是一个开源任务调度框架,可以根据用户设定的时间规则来执行作业。简单来说,用户可以提前设定时间,规定好该时间所需要做的任务,当到达设定时间时,该任务便会按照原先定好的流程运行。

运用场景

1.定时轮询数据库同步
2.定时邮件通知
3.定时在线考试
4.等等

Quartz核心组件 任务:JobDetail

Job(任务):是一个接口,可以通过实现该接口来定义需要执行的任务。
JobDetail是用来描述Job实现类以及相关静态信息,比如任务在scheduler中的任务名、组名等信息。

触发器:Trigger

描述触发Job执行的时间触发规则

调度器:Scheduler

用来连接Trigger和JobDetail,可以将Trigger绑定到某一JobDetail上,这样当Trigger被触发时,对应的Job就会执行

使用Quzrtz 导入依赖

使用的版本是2.3.5.RELEASE,可相应进行调整

org.springframework.boot spring-boot-starter-quartz 2.3.5.RELEASE

创建 QuartzManager类

该类的作用是提供定时任务的创建、修改、移除等操作

@Componentpublic class QuartzManager { private static final SchedulerFactory schedulerFactory = new StdSchedulerFactory(); @SuppressWarnings({ "unchecked", "rawtypes" }) public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cron) { try { Scheduler sched = schedulerFactory.getScheduler(); // 任务名,任务组,任务执行类 JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); // 触发器 TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 触发器时间设定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 创建Trigger对象 CronTrigger trigger = (CronTrigger) triggerBuilder.build(); // 调度容器设置JobDetail和Trigger sched.scheduleJob(jobDetail, trigger); // 启动 if (!sched.isShutdown()) { sched.start(); } } catch (Exception e) { throw new RuntimeException(e); } } public void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron) { try { Scheduler sched = schedulerFactory.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey); if (trigger == null) { return; } String oldTime = trigger.getCronexpression(); if (!oldTime.equalsIgnoreCase(cron)) { // 触发器 TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 触发器时间设定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 创建Trigger对象 trigger = (CronTrigger) triggerBuilder.build(); // 方式一 :修改一个任务的触发时间 sched.rescheduleJob(triggerKey, trigger); //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName)); //Class<? extends Job> jobClass = jobDetail.getJobClass(); //removeJob(jobName, jobGroupName, triggerName, triggerGroupName); //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); } } catch (Exception e) { throw new RuntimeException(e); } } public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { try { Scheduler sched = schedulerFactory.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); sched.pauseTrigger(triggerKey);// 停止触发器 sched.unscheduleJob(triggerKey);// 移除触发器 sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务 } catch (Exception e) { throw new RuntimeException(e); } } public void startJobs() { try { Scheduler sched = schedulerFactory.getScheduler(); sched.start(); } catch (Exception e) { throw new RuntimeException(e); } } public void shutdownJobs() { try { Scheduler sched = schedulerFactory.getScheduler(); if (!sched.isShutdown()) { sched.shutdown(); } } catch (Exception e) { throw new RuntimeException(e); } }}

创建QuartzCronDateUtils类

该类作用为将Date类型的数据转化为Cron类型的表达式。
由于Quartz定时任务使用的日期形式为corn,所以需要增加一个格式转换类。

public class QuartzCronDateUtils { public static String formatDateByPattern(Date date, String dateFormat) { SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); String formatTimeStr = null; if (date != null) { formatTimeStr = sdf.format(date); } return formatTimeStr; } public static String getCron(java.util.Date date) { String dateFormat = "ss mm HH dd MM ? yyyy"; return formatDateByPattern(date, dateFormat); }}

测试Quartz 创建SpringApplicationUtils类

该类的可以获取类对象的实例。
由于我们后面写任务逻辑(实现接口 Job类)时可能会需要进行一些方法的注入,例如在任务逻辑中需要使用我们自己写的一些service类,因为Quartz在实例化对象的时候没有经过Spring的处理,那么就意味着在Spring的IOC容器当中没有对应的对象,导致我们自己的一些类无法成功注入。因此需要使用SpringApplicationUtils中的getBean方法手动获取实例对象。

@Componentpublic class SpringApplicationUtils implements ApplicationContextAware { private static ApplicationContext applicationContext = null; public static ApplicationContext getApplicationContext() { return applicationContext; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringApplicationUtils.applicationContext == null) { SpringApplicationUtils.applicationContext = applicationContext; } } public static Object getBean(String name) { return getApplicationContext().getBean(name); } public static T getBean(Class clazz) { return getApplicationContext().getBean(clazz); } public static T getBean(String name, Class clazz) { return getApplicationContext().getBean(name, clazz); } public static Map getBeansOfType(Class clazz) { Map instances = getApplicationContext().getBeansOfType(clazz); return instances; }}

创建TestService类

@Service@Slf4jpublic class TestService { public void Test(){ log.info("Test....."); }}

创建TestQuartz类

实现Job接口中的execute方法,写定时任务逻辑

public class TestQuartz implements Job {//获取TestService类 TestService testService = SpringApplicationUtils.getBean(TestService.class); @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { testService.Test(); }}

创建QuartzJobListener类(不是必要的,可自行增减)

该类作用为创建定时任务

@Servicepublic class QuartzJobListener { @Autowired QuartzManager quartzManager; public void contextInitialized() { //此处模拟从数据库中获取的数据所得到的list List> listMap=new ArrayList<>(); //使用QuartzCronDateUtils.getCron将时间转为corn格式,new Date(122,1,8,23,0)对应的时间为2022年2月8号23点 String corn = QuartzCronDateUtils.getCron(new Date(122,1,8,23,0)); for(int i = 1; i <= 3; i++){ Map map = new HashMap(); map.put("jobName","jobName" + i); map.put("jobGroupName","jobGroupName" + i); map.put("triggerName","triggerName" + i); map.put("triggerGroupName","triggerGroupName" + i); map.put("jobTime",corn); listMap.add(map); } for (Map oneMap : listMap) { try { //创建定时任务,此时有三个定时任务,都在2022年2月8号23整点触发 quartzManager.addJob(oneMap.get("jobName").toString(),oneMap.get("jobGroupName").toString(), oneMap.get("triggerName").toString(), oneMap.get("triggerGroupName").toString(), TestQuartz.class, oneMap.get("jobTime").toString()); } catch (Exception e) { e.printStackTrace(); } } }}

创建ApplicationQuartzRunner类

该类作用为在项目启动时,开启定时任务(实际就是QuartzJobListener类中的创建定时任务)

@Componentpublic class ApplicationQuartzRunner implements ApplicationRunner { @Autowired QuartzJobListener quartzJobListener; @Override public void run(ApplicationArguments args) throws Exception { quartzJobListener.contextInitialized(); System.out.println("QuartzJobListener 启动了"); }}

结果

最后测试结果,三个定时任务都在2022年2月8号23整点触发了

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。