博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springBoot集成 quartz动态定时任务
阅读量:5239 次
发布时间:2019-06-14

本文共 13499 字,大约阅读时间需要 44 分钟。

项目中需要用到定时任务,考虑了下java方面定时任务无非就三种:

  1. 用Java自带的timer类。稍微看了一下,可以实现大部分的指定频率的任务的调度(timer.schedule()),也可以实现关闭和开启(timer.cancle)。但是用其来实现某天的某个时间或者某月的某一天调度任务有点不方便。
  2. 采用Quartz 调度器实现。这是一个功能很强大的开源的专门用于定时任务调度的框架,也很好的和springboot整合,缺点:配置复杂,需要花费一定的时间去了解和研究。
  3. spring3.0以后自带的scheduletask任务调度,可以实现quartz的大部分功能,不需要额外引用jar,也不需要另外配置。而且支持注解和配置文件两种。

  鉴于项目有些地方要考虑动态管理定时任务的,所以考虑吧quartz也集成进去,方便调用。

  一、首先引入依赖(必需)

org.quartz-scheduler
quartz
2.2.3
org.quartz-scheduler
quartz-jobs
2.2.3
    

二、创建job 实例工厂,解决spring注入问题,如果使用默认会导致spring的@Autowired 无法注入问题

1 package com.qunyi.jifenzhi_zx.core.quartz.taskjobfactory; 2  3 import org.quartz.spi.TriggerFiredBundle; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 6 import org.springframework.scheduling.quartz.AdaptableJobFactory; 7 import org.springframework.stereotype.Component; 8  9 /**10  * @author xujingyang11  * @Description: 解决quartz无法注入spring bean问题12  * @date 2018/5/30.13  */14 @Component15 public class TaskJobFactory extends AdaptableJobFactory {16     @Autowired17     private AutowireCapableBeanFactory capableBeanFactory;18 19     @Override20     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {21         //调用父类的方法22         Object jobInstance = super.createJobInstance(bundle);23         //进行注入24         capableBeanFactory.autowireBean(jobInstance);25         return jobInstance;26     }27 }
TaskJobFactory

 

三、创建job管理类,对job进行增加,暂停,恢复,更新,删除等操作

import com.qunyi.jifenzhi_zx.common.core.quartz.BaseTaskJob;import org.quartz.*;import org.quartz.impl.matchers.GroupMatcher;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.util.*;/** * @author xujingyang * @Description: task任务创建工具类 * @date 2018/5/30. */@Componentpublic class QuartzJobManager {    private static final Logger logger = LoggerFactory.getLogger(QuartzJobManager.class);    private static QuartzJobManager jobUtil;    @Autowired    private Scheduler scheduler;    public QuartzJobManager() {        logger.info("init jobUtil");        jobUtil = this;    }    public static QuartzJobManager getInstance() {        logger.info("retun  JobCreateUtil");        return QuartzJobManager.jobUtil;    }    /**     * 创建job     *     * @param clazz          任务类     * @param jobName        任务名称     * @param jobGroupName   任务所在组名称     * @param cronExpression cron表达式     * @throws Exception     * @author xujingyang     * @date 2018/5/30.     */    public void addJob(Class clazz, String jobName, String jobGroupName, String cronExpression) throws Exception {        // 启动调度器        scheduler.start();        //构建job信息        JobDetail jobDetail = JobBuilder.newJob(((BaseTaskJob) clazz.newInstance()).getClass()).withIdentity(jobName, jobGroupName).build();        //表达式调度构建器(即任务执行的时间)        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);        //按新的cronExpression表达式构建一个新的trigger        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)                .withSchedule(scheduleBuilder).build();        scheduler.scheduleJob(jobDetail, trigger);    }    /**     * 创建job,可传参     *     * @param clazz          任务类     * @param jobName        任务名称     * @param jobGroupName   任务所在组名称     * @param cronExpression cron表达式     * @param argMap         map形式参数     * @throws Exception     * @author xujingyang     * @date 2018/5/30.     */    public void addJob(Class clazz, String jobName, String jobGroupName, String cronExpression, Map
argMap) throws Exception { // 启动调度器 scheduler.start(); //构建job信息 JobDetail jobDetail = JobBuilder.newJob(((BaseTaskJob) clazz.newInstance()).getClass()).withIdentity(jobName, jobGroupName).build(); //表达式调度构建器(即任务执行的时间) CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); //按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName) .withSchedule(scheduleBuilder).build(); //获得JobDataMap,写入数据 trigger.getJobDataMap().putAll(argMap); scheduler.scheduleJob(jobDetail, trigger); } /** * 暂停job * * @param jobName 任务名称 * @param jobGroupName 任务所在组名称 * @throws SchedulerException * @author xujingyang * @date 2018/5/30. */ public void pauseJob(String jobName, String jobGroupName) throws SchedulerException { scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName)); } /** * 恢复job * * @param jobName 任务名称 * @param jobGroupName 任务所在组名称 * @throws SchedulerException * @author xujingyang * @date 2018/5/30. */ public void resumeJob(String jobName, String jobGroupName) throws SchedulerException { scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName)); } /** * job 更新,只更新频率 * * @param jobName 任务名称 * @param jobGroupName 任务所在组名称 * @param cronExpression cron表达式 * @throws Exception * @author xujingyang * @date 2018/5/30. */ public void updateJob(String jobName, String jobGroupName, String cronExpression) throws Exception { TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName); // 表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } /** * job 更新,更新频率和参数 * * @param jobName 任务名称 * @param jobGroupName 任务所在组名称 * @param cronExpression cron表达式 * @param argMap 参数 * @throws Exception * @author xujingyang * @date 2018/5/30. */ public void updateJob(String jobName, String jobGroupName, String cronExpression, Map
argMap) throws Exception { TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName); // 表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); //修改map trigger.getJobDataMap().putAll(argMap); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } /** * job 更新,只更新更新参数 * * @param jobName 任务名称 * @param jobGroupName 任务所在组名称 * @param argMap 参数 * @throws Exception * @author xujingyang * @date 2018/5/30. */ public void updateJob(String jobName, String jobGroupName, Map
argMap) throws Exception { TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //修改map trigger.getJobDataMap().putAll(argMap); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } /** * job 删除 * * @param jobName 任务名称 * @param jobGroupName 任务所在组名称 * @throws Exception * @author xujingyang * @date 2018/5/30. */ public void deleteJob(String jobName, String jobGroupName) throws Exception { scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName)); scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName)); scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName)); } /** * 启动所有定时任务 * * @author xujingyang * @date 2018/5/30. */ public void startAllJobs() { try { scheduler.start(); } catch (Exception e) { throw new RuntimeException(e); } } /** * 关闭所有定时任务 * * @author xujingyang * @date 2018/5/30. */ public void shutdownAllJobs() { try { if (!scheduler.isShutdown()) { scheduler.shutdown(); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 获取所有任务列表 * * @return * @throws SchedulerException */ public List
> getAllJob() throws SchedulerException { GroupMatcher
matcher = GroupMatcher.anyJobGroup(); Set
jobKeys = scheduler.getJobKeys(matcher); List
> jobList = new ArrayList<>(); for (JobKey jobKey : jobKeys) { List
triggers = scheduler.getTriggersOfJob(jobKey); for (Trigger trigger : triggers) { Map
job = new HashMap<>(); job.put("jobName", jobKey.getName()); job.put("jobGroupName", jobKey.getGroup()); job.put("trigger", trigger.getKey()); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); job.put("jobStatus", triggerState.name()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.put("cronExpression", cronExpression); } jobList.add(job); } } return jobList; }}
QuartzJobManager

 

四、增加quartz 属性配置文件 quartz.properties,放置resource目录下,此文件主要提供schedule自动注入提供属性

# 固定前缀org.quartzorg.quartz.scheduler.instanceName = DefaultQuartzSchedulerorg.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export = falseorg.quartz.scheduler.rmi.proxy = falseorg.quartz.scheduler.wrapJobExecutionInUserTransaction = false

 

五、创建quartz的配置文件QuartzrConfiguration,进行属性配置

1 package com.qunyi.jifenzhi_zx.core.config; 2  3 import com.qunyi.jifenzhi_zx.core.quartz.taskjobfactory.TaskJobFactory; 4 import org.quartz.Scheduler; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.config.PropertiesFactoryBean; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.core.io.ClassPathResource;10 import org.springframework.scheduling.quartz.SchedulerFactoryBean;11 12 import javax.sql.DataSource;13 import java.io.IOException;14 15 /**16  * @author xujingyang17  * @Description: 任务调度配置18  * @date 2018/5/30.19  */20 @Configuration21 public class QuartzConfiguration {22     @Autowired23     private DataSource dataSource;24     @Autowired25     private TaskJobFactory jobFactory;26 27     @Bean(name = "SchedulerFactory")28     public SchedulerFactoryBean schedulerFactoryBean() throws IOException {29         //获取配置属性30         PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();31         propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));32         //在quartz.properties中的属性被读取并注入后再初始化对象33         propertiesFactoryBean.afterPropertiesSet();34         //创建SchedulerFactoryBean35         SchedulerFactoryBean factory = new SchedulerFactoryBean();36         factory.setQuartzProperties(propertiesFactoryBean.getObject());37         factory.setJobFactory(jobFactory);38         return factory;39     }40 41     /*42      * 通过SchedulerFactoryBean获取Scheduler的实例43      */44     @Bean(name = "scheduler")45     public Scheduler scheduler() throws IOException {46         return schedulerFactoryBean().getScheduler();47     }48 }

 

六、创建基础任务调度接口

1 package com.qunyi.jifenzhi_zx.core.quartz; 2  3 import org.quartz.Job; 4 import org.quartz.JobExecutionContext; 5 import org.quartz.JobExecutionException; 6  7 /** 8  * @author xujingyang 9  * @Description: 基础任务调度taskJob接口10  * @date 2018/5/3011  * 

12 */13 public interface BaseTaskJob extends Job {14 void execute(JobExecutionContext context)15 throws JobExecutionException;16 }

 

七、创建任务实现类

1 package com.qunyi.jifenzhi_zx.module.taskJob; 2  3 import com.qunyi.jifenzhi_zx.core.quartz.BaseTaskJob; 4 import org.quartz.JobExecutionContext; 5 import org.quartz.JobExecutionException; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import org.springframework.stereotype.Component; 9 10 @Component11 public class TestQuartz implements BaseTaskJob {12 13     Logger logger = LoggerFactory.getLogger(this.getClass());14 15     public  int i = 0;16 17     @Override18     public void execute(JobExecutionContext context) throws JobExecutionException {19         i++;20         logger.error("task2>>>>>>>  " + i);21 22         try {23 //            QuartzJobManager.getInstance().jobdelete(this.getClass().getSimpleName(),"ah");//执行完此任务就删除自己24         } catch (Exception e) {25             e.printStackTrace();26         }27     }28 }

 

八、创建controller测试动态添加任务

1 @PostMapping("/task")2     public void task(HttpServletRequest request) throws Exception {3         String name = PrimaryKeyUtil.nextId();4         QuartzJobManager.getInstance().addJob(TestQuartz.class, name, "*/1 * * * * ?");5     }

 

九、访问测试结果

总结及注意:

  这种任务执行时是整个类都要初始化一遍的,不像spring的schedule只初始执行方法,这种每次执行类中的变量都会初始化。

  添加新任务调度时,只需要新建类然后继承任务接口实现方法即可,这样在添加任务的时候只需要传新建类的class就可以了。

  传同一个class的时候,是同一个任务方法,只不过新建了开了一个线程来执行而已。

 

  

 

转载于:https://www.cnblogs.com/xujingyang/p/9115328.html

你可能感兴趣的文章
了解循环队列的实现
查看>>
CentOS 简单命令
查看>>
Linux中修改docker镜像源及安装docker
查看>>
数位dp(模板+例题)
查看>>
Android 自动安装脚本
查看>>
[编程之美]电梯调度算法
查看>>
常用的jQuery九宫格布局图片展示特效代码
查看>>
scrollView的bounds
查看>>
【洛谷】[FJOI2018]领导集团问题
查看>>
《springcloud 三》分布式配置中心
查看>>
Java基础知识强化之集合框架笔记06:Collection集合存储自定义对象并遍历的案例...
查看>>
Android(java)学习笔记25:Android 手机拨号
查看>>
Linux ftp访问控制配置,包括访问ftp权限和访问ftp目录权限
查看>>
leetcode[148]Sort List
查看>>
ES6 Array扩展 学习笔记
查看>>
Swoole WebSocket 的应用
查看>>
Linux源码编译安装nginx
查看>>
Java异常知识处理_NoClassDefFoundError和ClassNotFoundException有什么区别
查看>>
[bbk5388] 第91集 -第11章 -数据库诊断 07
查看>>
CentOS7 安装 JIRA 7.2.x 教程:下载、安装、汉化、破解
查看>>