springboot+Quartz实现任务调度的示例代码
在spring框架中通过@Schedule可以实现定时任务,通过该注解cron的属性描述的规则,spring会去调用这个方法。
spring已经简单粗暴的实现了定时任务,为什么要使用Quartz?
如果你现在有很多个定时任务,规则不同,例如:
- 想每月25号,信用卡自动还款
- 想每年4月1日自己给当年暗恋女神发一封匿名贺卡
- 想每隔1小时,备份一下自己的爱情动作片学习笔记到云盘
maven依赖
org.quartz-scheduler quartz 2.2.1 org.quartz-scheduler quartz-jobs 2.2.1
以下是bootdo开源学习框架的源码
我并没有用到全部的字段,思路是先查询DB,
封装以下两个对象
- JobDetail负责存放job所需要的数据
- Trigger设置job的key,规则(cron)何时开启任务等属性
当触发条件满足时,会根据所设置的beanClass找到该类(必须实现org.quartz.Job),这时可以取出JobDetail中的数据,执行具体业务逻辑
@Component publicclassWelcomeJobimplementsJob{ @Override publicvoidexecute(JobExecutionContextarg0)throwsJobExecutionException{ //你的业务逻辑 } }
表结构
CREATETABLE`sys_task`( `id`bigint(20)NOTNULLAUTO_INCREMENT, `cronExpression`varchar(255)DEFAULTNULLCOMMENT'cron表达式', `methodName`varchar(255)DEFAULTNULLCOMMENT'任务调用的方法名', `isConcurrent`varchar(255)DEFAULTNULLCOMMENT'任务是否有状态', `description`varchar(255)DEFAULTNULLCOMMENT'任务描述', `updateBy`varchar(64)DEFAULTNULLCOMMENT'更新者', `beanClass`varchar(255)DEFAULTNULLCOMMENT'任务执行时调用哪个类的方法包名+类名', `createDate`datetimeDEFAULTNULLCOMMENT'创建时间', `jobStatus`varchar(255)DEFAULTNULLCOMMENT'任务状态', `jobGroup`varchar(255)DEFAULTNULLCOMMENT'任务分组', `updateDate`datetimeDEFAULTNULLCOMMENT'更新时间', `createBy`varchar(64)DEFAULTNULLCOMMENT'创建者', `springBean`varchar(255)DEFAULTNULLCOMMENT'Springbean', `jobName`varchar(255)DEFAULTNULLCOMMENT'任务名', PRIMARYKEY(`id`) )ENGINE=InnoDBAUTO_INCREMENT=3DEFAULTCHARSET=utf8ROW_FORMAT=COMPACT;
配置类
importjava.io.IOException; importjava.util.Properties; importorg.quartz.Scheduler; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.config.PropertiesFactoryBean; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.core.io.ClassPathResource; importorg.springframework.scheduling.quartz.SchedulerFactoryBean; importcom.txgl.common.quartz.factory.JobFactory; @Configuration publicclassQuartzConfigration{ @Autowired JobFactoryjobFactory; @Bean publicSchedulerFactoryBeanschedulerFactoryBean(){ SchedulerFactoryBeanschedulerFactoryBean=newSchedulerFactoryBean(); try{ schedulerFactoryBean.setOverwriteExistingJobs(true); schedulerFactoryBean.setQuartzProperties(quartzProperties()); schedulerFactoryBean.setJobFactory(jobFactory); }catch(IOExceptione){ e.printStackTrace(); } returnschedulerFactoryBean; } //指定quartz.properties @Bean publicPropertiesquartzProperties()throwsIOException{ PropertiesFactoryBeanpropertiesFactoryBean=newPropertiesFactoryBean(); propertiesFactoryBean.setLocation(newClassPathResource("/config/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); returnpropertiesFactoryBean.getObject(); } //创建schedule @Bean(name="scheduler") publicSchedulerscheduler(){ returnschedulerFactoryBean().getScheduler(); } }
QuartzManager的代码是关键,通过注入Scheduler对任务进行操作
importjava.util.ArrayList; importjava.util.List; importjava.util.Set; importorg.apache.log4j.Logger; importorg.quartz.CronScheduleBuilder; importorg.quartz.CronTrigger; importorg.quartz.DateBuilder; importorg.quartz.DateBuilder.IntervalUnit; importorg.quartz.Job; importorg.quartz.JobBuilder; importorg.quartz.JobDetail; importorg.quartz.JobExecutionContext; importorg.quartz.JobKey; importorg.quartz.Scheduler; importorg.quartz.SchedulerException; importorg.quartz.Trigger; importorg.quartz.TriggerBuilder; importorg.quartz.TriggerKey; importorg.quartz.impl.matchers.GroupMatcher; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.annotation.Qualifier; importorg.springframework.scheduling.quartz.SchedulerFactoryBean; importorg.springframework.stereotype.Service; importorg.springframework.web.context.support.SpringBeanAutowiringSupport; importcom.bootdo.common.domain.ScheduleJob; importcom.bootdo.common.quartz.factory.*; importcom.bootdo.common.utils.SpringContextHolder;; /** * * *@title:QuartzManager.java *@description:计划任务管理 * */ @Service publicclassQuartzManager{ publicfinalLoggerlog=Logger.getLogger(this.getClass()); //privateSchedulerFactoryBeanschedulerFactoryBean //=SpringContextHolder.getBean(SchedulerFactoryBean.class); //@Autowired //@Qualifier("schedulerFactoryBean") //privateSchedulerFactoryBeanschedulerFactoryBean; @Autowired privateSchedulerscheduler; /** *添加任务 * *@paramscheduleJob *@throwsSchedulerException */ publicvoidaddJob(ScheduleJobjob){ try{ //创建jobDetail实例,绑定Job实现类 //指明job的名称,所在组的名称,以及绑定job类 ClassjobClass=(Class)(Class.forName(job.getBeanClass()).newInstance() .getClass()); JobDetailjobDetail=JobBuilder.newJob(jobClass).withIdentity(job.getJobName(),job.getJobGroup())//任务名称和组构成任务key .build(); //定义调度触发规则 //使用cornTrigger规则 Triggertrigger=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(Exceptione){ e.printStackTrace(); } } //publicvoidaddJob(ScheduleJobjob)throwsSchedulerException{ //if(job==null||!ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())){ //return; //} // //TriggerKeytriggerKey=TriggerKey.triggerKey(job.getJobName(),job.getJobGroup()); // //CronTriggertrigger=(CronTrigger)scheduler.getTrigger(triggerKey); // ////不存在,创建一个 // //if(null==trigger){ //Classclazz=ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent()) //?QuartzJobFactory.class //:QuartzJobFactoryDisallowConcurrentExecution.class; // //JobDetailjobDetail=JobBuilder.newJob(clazz).withIdentity(job.getJobName(),job.getJobGroup()).build(); // //jobDetail.getJobDataMap().put("scheduleJob",job); // //CronScheduleBuilderscheduleBuilder=CronScheduleBuilder.cronSchedule(job.getCronExpression()); // //trigger=TriggerBuilder.newTrigger().withIdentity(job.getJobName(),job.getJobGroup()) //.withSchedule(scheduleBuilder).build(); // //scheduler.scheduleJob(jobDetail,trigger); //}else{ ////Trigger已存在,那么更新相应的定时设置 // //CronScheduleBuilderscheduleBuilder=CronScheduleBuilder.cronSchedule(job.getCronExpression()); // ////按新的cronExpression表达式重新构建trigger // //trigger=trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // ////按新的trigger重新设置job执行 // //scheduler.rescheduleJob(triggerKey,trigger); //} //} /** *获取所有计划中的任务列表 * *@return *@throwsSchedulerException */ publicListgetAllJob()throwsSchedulerException{ GroupMatcher matcher=GroupMatcher.anyJobGroup(); Set jobKeys=scheduler.getJobKeys(matcher); List jobList=newArrayList (); for(JobKeyjobKey:jobKeys){ Listtriggers=scheduler.getTriggersOfJob(jobKey); for(Triggertrigger:triggers){ ScheduleJobjob=newScheduleJob(); job.setJobName(jobKey.getName()); job.setJobGroup(jobKey.getGroup()); job.setDescription("触发器:"+trigger.getKey()); Trigger.TriggerStatetriggerState=scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if(triggerinstanceofCronTrigger){ CronTriggercronTrigger=(CronTrigger)trigger; StringcronExpression=cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); } } returnjobList; } /** *所有正在运行的job * *@return *@throwsSchedulerException */ publicList getRunningJob()throwsSchedulerException{ List executingJobs=scheduler.getCurrentlyExecutingJobs(); List jobList=newArrayList (executingJobs.size()); for(JobExecutionContextexecutingJob:executingJobs){ ScheduleJobjob=newScheduleJob(); JobDetailjobDetail=executingJob.getJobDetail(); JobKeyjobKey=jobDetail.getKey(); Triggertrigger=executingJob.getTrigger(); job.setJobName(jobKey.getName()); job.setJobGroup(jobKey.getGroup()); job.setDescription("触发器:"+trigger.getKey()); Trigger.TriggerStatetriggerState=scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if(triggerinstanceofCronTrigger){ CronTriggercronTrigger=(CronTrigger)trigger; StringcronExpression=cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); } returnjobList; } /** *暂停一个job * *@paramscheduleJob *@throwsSchedulerException */ publicvoidpauseJob(ScheduleJobscheduleJob)throwsSchedulerException{ JobKeyjobKey=JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()); scheduler.pauseJob(jobKey); } /** *恢复一个job * *@paramscheduleJob *@throwsSchedulerException */ publicvoidresumeJob(ScheduleJobscheduleJob)throwsSchedulerException{ JobKeyjobKey=JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()); scheduler.resumeJob(jobKey); } /** *删除一个job * *@paramscheduleJob *@throwsSchedulerException */ publicvoiddeleteJob(ScheduleJobscheduleJob)throwsSchedulerException{ JobKeyjobKey=JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey); } /** *立即执行job * *@paramscheduleJob *@throwsSchedulerException */ publicvoidrunAJobNow(ScheduleJobscheduleJob)throwsSchedulerException{ JobKeyjobKey=JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()); scheduler.triggerJob(jobKey); } /** *更新job时间表达式 * *@paramscheduleJob *@throwsSchedulerException */ publicvoidupdateJobCron(ScheduleJobscheduleJob)throwsSchedulerException{ TriggerKeytriggerKey=TriggerKey.triggerKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()); CronTriggertrigger=(CronTrigger)scheduler.getTrigger(triggerKey); CronScheduleBuilderscheduleBuilder=CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()); trigger=trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); scheduler.rescheduleJob(triggerKey,trigger); } }
service实现
importcom.bootdo.common.config.Constant; importcom.bootdo.common.dao.TaskDao; importcom.bootdo.common.domain.ScheduleJob; importcom.bootdo.common.domain.TaskDO; importcom.bootdo.common.quartz.utils.QuartzManager; importcom.bootdo.common.service.JobService; importcom.bootdo.common.utils.ScheduleJobUtils; importorg.quartz.SchedulerException; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.stereotype.Service; importjava.util.HashMap; importjava.util.List; importjava.util.Map; @Service publicclassJobServiceImplimplementsJobService{ @Autowired privateTaskDaotaskScheduleJobMapper; @Autowired QuartzManagerquartzManager; @Override publicTaskDOget(Longid){ returntaskScheduleJobMapper.get(id); } @Override publicListlist(Map map){ returntaskScheduleJobMapper.list(map); } @Override publicintcount(Map map){ returntaskScheduleJobMapper.count(map); } @Override publicintsave(TaskDOtaskScheduleJob){ returntaskScheduleJobMapper.save(taskScheduleJob); } @Override publicintupdate(TaskDOtaskScheduleJob){ returntaskScheduleJobMapper.update(taskScheduleJob); } @Override publicintremove(Longid){ try{ TaskDOscheduleJob=get(id); quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob)); returntaskScheduleJobMapper.remove(id); }catch(SchedulerExceptione){ e.printStackTrace(); return0; } } @Override publicintbatchRemove(Long[]ids){ for(Longid:ids){ try{ TaskDOscheduleJob=get(id); quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob)); }catch(SchedulerExceptione){ e.printStackTrace(); return0; } } returntaskScheduleJobMapper.batchRemove(ids); } @Override publicvoidinitSchedule()throwsSchedulerException{ //这里获取任务信息数据 List jobList=taskScheduleJobMapper.list(newHashMap (16)); for(TaskDOscheduleJob:jobList){ if("1".equals(scheduleJob.getJobStatus())){ ScheduleJobjob=ScheduleJobUtils.entityToData(scheduleJob); quartzManager.addJob(job); } } } @Override publicvoidchangeStatus(LongjobId,Stringcmd)throwsSchedulerException{ TaskDOscheduleJob=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 publicvoidupdateCron(LongjobId)throwsSchedulerException{ TaskDOscheduleJob=get(jobId); if(scheduleJob==null){ return; } if(ScheduleJob.STATUS_RUNNING.equals(scheduleJob.getJobStatus())){ quartzManager.updateJobCron(ScheduleJobUtils.entityToData(scheduleJob)); } update(scheduleJob); } }
启动一个监听去初始化Quartz
importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.boot.CommandLineRunner; importorg.springframework.core.annotation.Order; importorg.springframework.stereotype.Component; importcom.bootdo.common.quartz.utils.QuartzManager; importcom.bootdo.common.service.JobService; @Component @Order(value=1) publicclassScheduleJobInitListenerimplementsCommandLineRunner{ @Autowired JobServicescheduleJobService; @Autowired QuartzManagerquartzManager; @Override publicvoidrun(String...arg0)throwsException{ try{ scheduleJobService.initSchedule(); }catch(Exceptione){ e.printStackTrace(); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。