首页 > 编程 > Java > 正文

springboot+Quartz实现任务调度的示例代码

2019-11-26 10:20:30
字体:
来源:转载
供稿:网友

在spring框架中通过 @Schedule 可以实现定时任务,通过该注解 cron 的属性描述的规则,spring会去调用这个方法。

spring已经简单粗暴的实现了定时任务,为什么要使用Quartz ?

如果你现在有很多个定时任务,规则不同,例如:

  1. 想每月25号,信用卡自动还款
  2. 想每年4月1日自己给当年暗恋女神发一封匿名贺卡
  3. 想每隔1小时,备份一下自己的爱情动作片 学习笔记到云盘

maven 依赖

<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>

以下是bootdo开源学习框架的源码

我并没有用到全部的字段,思路是先查询DB,

封装以下两个对象

  1. JobDetail 负责存放 job 所需要的数据
  2. Trigger 设置 job 的 key,规则(cron)何时开启任务等属性

当触发条件满足时,会根据所设置的beanClass 找到该类(必须实现org.quartz.Job), 这时可以取出JobDetail 中的数据,执行具体业务逻辑

@Componentpublic class WelcomeJob implements Job{  @Override  public void execute(JobExecutionContext arg0) throws JobExecutionException {    //你的业务逻辑  }}

表结构

CREATE TABLE `sys_task` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `cronExpression` varchar(255) DEFAULT NULL COMMENT 'cron表达式', `methodName` varchar(255) DEFAULT NULL COMMENT '任务调用的方法名', `isConcurrent` varchar(255) DEFAULT NULL COMMENT '任务是否有状态', `description` varchar(255) DEFAULT NULL COMMENT '任务描述', `updateBy` varchar(64) DEFAULT NULL COMMENT '更新者', `beanClass` varchar(255) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名', `createDate` datetime DEFAULT NULL COMMENT '创建时间', `jobStatus` varchar(255) DEFAULT NULL COMMENT '任务状态', `jobGroup` varchar(255) DEFAULT NULL COMMENT '任务分组', `updateDate` datetime DEFAULT NULL COMMENT '更新时间', `createBy` varchar(64) DEFAULT NULL COMMENT '创建者', `springBean` varchar(255) DEFAULT NULL COMMENT 'Spring bean', `jobName` varchar(255) DEFAULT NULL COMMENT '任务名', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

配置类

import java.io.IOException;import java.util.Properties;import org.quartz.Scheduler;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.config.PropertiesFactoryBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import com.txgl.common.quartz.factory.JobFactory;@Configurationpublic class QuartzConfigration {  @Autowired  JobFactory jobFactory;  @Bean  public SchedulerFactoryBean schedulerFactoryBean() {    SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();    try {      schedulerFactoryBean.setOverwriteExistingJobs(true);      schedulerFactoryBean.setQuartzProperties(quartzProperties());      schedulerFactoryBean.setJobFactory(jobFactory);    } catch (IOException e) {      e.printStackTrace();    }    return schedulerFactoryBean;  }  // 指定quartz.properties  @Bean  public Properties quartzProperties() throws IOException {    PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();    propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));    propertiesFactoryBean.afterPropertiesSet();    return propertiesFactoryBean.getObject();  }  // 创建schedule  @Bean(name = "scheduler")  public Scheduler scheduler() {    return schedulerFactoryBean().getScheduler();  }}

QuartzManager的代码是关键,通过注入Scheduler 对任务进行操作

import java.util.ArrayList;import java.util.List;import java.util.Set;import org.apache.log4j.Logger;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.DateBuilder;import org.quartz.DateBuilder.IntervalUnit;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDetail;import org.quartz.JobExecutionContext;import org.quartz.JobKey;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.Trigger;import org.quartz.TriggerBuilder;import org.quartz.TriggerKey;import org.quartz.impl.matchers.GroupMatcher;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import org.springframework.stereotype.Service;import org.springframework.web.context.support.SpringBeanAutowiringSupport;import com.bootdo.common.domain.ScheduleJob;import com.bootdo.common.quartz.factory.*;import com.bootdo.common.utils.SpringContextHolder;;/** *  *  * @title: QuartzManager.java * @description: 计划任务管理 * */@Servicepublic class QuartzManager {  public final Logger log = Logger.getLogger(this.getClass());  // private SchedulerFactoryBean schedulerFactoryBean  // =SpringContextHolder.getBean(SchedulerFactoryBean.class);  // @Autowired  // @Qualifier("schedulerFactoryBean")  // private SchedulerFactoryBean schedulerFactoryBean;  @Autowired  private Scheduler scheduler;  /**   * 添加任务   *    * @param scheduleJob   * @throws SchedulerException   */    public void addJob(ScheduleJob job) {    try {      // 创建jobDetail实例,绑定Job实现类      // 指明job的名称,所在组的名称,以及绑定job类      Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(job.getBeanClass()).newInstance()          .getClass());      JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(job.getJobName(), job.getJobGroup())// 任务名称和组构成任务key          .build();      // 定义调度触发规则      // 使用cornTrigger规则      Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())// 触发器key          .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))          .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())).startNow().build();      // 把作业和触发器注册到任务调度中      scheduler.scheduleJob(jobDetail, trigger);      // 启动      if (!scheduler.isShutdown()) {        scheduler.start();      }    } catch (Exception e) {      e.printStackTrace();    }  }// public void addJob(ScheduleJob job) throws SchedulerException {//   if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {//     return;//   }////   TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());////   CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);////   // 不存在,创建一个////   if (null == trigger) {//     Class<? extends Job> clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent())//         ? QuartzJobFactory.class//         : QuartzJobFactoryDisallowConcurrentExecution.class;////     JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();////     jobDetail.getJobDataMap().put("scheduleJob", job);////     CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());////     trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())//         .withSchedule(scheduleBuilder).build();////     scheduler.scheduleJob(jobDetail, trigger);//   } else {//     // Trigger已存在,那么更新相应的定时设置////     CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());////     // 按新的cronExpression表达式重新构建trigger////     trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();////     // 按新的trigger重新设置job执行////     scheduler.rescheduleJob(triggerKey, trigger);//   }// }  /**   * 获取所有计划中的任务列表   *    * @return   * @throws SchedulerException   */  public List<ScheduleJob> getAllJob() throws SchedulerException {    GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();    Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);    List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();    for (JobKey jobKey : jobKeys) {      List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);      for (Trigger trigger : triggers) {        ScheduleJob job = new ScheduleJob();        job.setJobName(jobKey.getName());        job.setJobGroup(jobKey.getGroup());        job.setDescription("触发器:" + trigger.getKey());        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());        job.setJobStatus(triggerState.name());        if (trigger instanceof CronTrigger) {          CronTrigger cronTrigger = (CronTrigger) trigger;          String cronExpression = cronTrigger.getCronExpression();          job.setCronExpression(cronExpression);        }        jobList.add(job);      }    }    return jobList;  }  /**   * 所有正在运行的job   *    * @return   * @throws SchedulerException   */  public List<ScheduleJob> getRunningJob() throws SchedulerException {    List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();    List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());    for (JobExecutionContext executingJob : executingJobs) {      ScheduleJob job = new ScheduleJob();      JobDetail jobDetail = executingJob.getJobDetail();      JobKey jobKey = jobDetail.getKey();      Trigger trigger = executingJob.getTrigger();      job.setJobName(jobKey.getName());      job.setJobGroup(jobKey.getGroup());      job.setDescription("触发器:" + trigger.getKey());      Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());      job.setJobStatus(triggerState.name());      if (trigger instanceof CronTrigger) {        CronTrigger cronTrigger = (CronTrigger) trigger;        String cronExpression = cronTrigger.getCronExpression();        job.setCronExpression(cronExpression);      }      jobList.add(job);    }    return jobList;  }  /**   * 暂停一个job   *    * @param scheduleJob   * @throws SchedulerException   */  public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException {    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());    scheduler.pauseJob(jobKey);  }  /**   * 恢复一个job   *    * @param scheduleJob   * @throws SchedulerException   */  public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException {    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());    scheduler.resumeJob(jobKey);  }  /**   * 删除一个job   *    * @param scheduleJob   * @throws SchedulerException   */  public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());    scheduler.deleteJob(jobKey);  }  /**   * 立即执行job   *    * @param scheduleJob   * @throws SchedulerException   */  public void runAJobNow(ScheduleJob scheduleJob) throws SchedulerException {    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());    scheduler.triggerJob(jobKey);  }  /**   * 更新job时间表达式   *    * @param scheduleJob   * @throws SchedulerException   */  public void updateJobCron(ScheduleJob scheduleJob) throws SchedulerException {    TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();    scheduler.rescheduleJob(triggerKey, trigger);  }}

service实现

import com.bootdo.common.config.Constant;import com.bootdo.common.dao.TaskDao;import com.bootdo.common.domain.ScheduleJob;import com.bootdo.common.domain.TaskDO;import com.bootdo.common.quartz.utils.QuartzManager;import com.bootdo.common.service.JobService;import com.bootdo.common.utils.ScheduleJobUtils;import org.quartz.SchedulerException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.List;import java.util.Map;@Servicepublic class JobServiceImpl implements JobService {  @Autowired  private TaskDao taskScheduleJobMapper;  @Autowired  QuartzManager quartzManager;  @Override  public TaskDO get(Long id) {    return taskScheduleJobMapper.get(id);  }  @Override  public List<TaskDO> list(Map<String, Object> map) {    return taskScheduleJobMapper.list(map);  }  @Override  public int count(Map<String, Object> map) {    return taskScheduleJobMapper.count(map);  }  @Override  public int save(TaskDO taskScheduleJob) {    return taskScheduleJobMapper.save(taskScheduleJob);  }  @Override  public int update(TaskDO taskScheduleJob) {    return taskScheduleJobMapper.update(taskScheduleJob);  }  @Override  public int remove(Long id) {    try {      TaskDO scheduleJob = get(id);      quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob));      return taskScheduleJobMapper.remove(id);    } catch (SchedulerException e) {      e.printStackTrace();      return 0;    }  }  @Override  public int batchRemove(Long[] ids) {    for (Long id : ids) {      try {        TaskDO scheduleJob = get(id);        quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob));      } catch (SchedulerException e) {        e.printStackTrace();        return 0;      }    }    return taskScheduleJobMapper.batchRemove(ids);  }  @Override  public void initSchedule() throws SchedulerException {    // 这里获取任务信息数据    List<TaskDO> jobList = taskScheduleJobMapper.list(new HashMap<String, Object>(16));    for (TaskDO scheduleJob : jobList) {      if ("1".equals(scheduleJob.getJobStatus())) {        ScheduleJob job = ScheduleJobUtils.entityToData(scheduleJob);        quartzManager.addJob(job);      }    }  }  @Override  public void changeStatus(Long jobId, String cmd) throws SchedulerException {    TaskDO scheduleJob = get(jobId);    if (scheduleJob == null) {      return;    }    if (Constant.STATUS_RUNNING_STOP.equals(cmd)) {      quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob));      scheduleJob.setJobStatus(ScheduleJob.STATUS_NOT_RUNNING);    } else {      if (!Constant.STATUS_RUNNING_START.equals(cmd)) {      } else {        scheduleJob.setJobStatus(ScheduleJob.STATUS_RUNNING);        quartzManager.addJob(ScheduleJobUtils.entityToData(scheduleJob));      }    }    update(scheduleJob);  }  @Override  public void updateCron(Long jobId) throws SchedulerException {    TaskDO scheduleJob = get(jobId);    if (scheduleJob == null) {      return;    }    if (ScheduleJob.STATUS_RUNNING.equals(scheduleJob.getJobStatus())) {      quartzManager.updateJobCron(ScheduleJobUtils.entityToData(scheduleJob));    }    update(scheduleJob);  }}

启动一个监听去初始化Quartz

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;import com.bootdo.common.quartz.utils.QuartzManager;import com.bootdo.common.service.JobService;@Component@Order(value = 1)public class ScheduleJobInitListener implements CommandLineRunner {  @Autowired  JobService scheduleJobService;  @Autowired  QuartzManager quartzManager;  @Override  public void run(String... arg0) throws Exception {    try {      scheduleJobService.initSchedule();    } catch (Exception e) {      e.printStackTrace();    }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表