最简单的用配置文件设置定时任务
<!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法--> <bean id="taskJob" class="com.tyyd.dw.task.DataConversionTask"/> <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="group" value="job_work"/> <property name="name" value="job_work_name"/> <!--false表示等上一个任务执行完后再开启新的任务--> <property name="concurrent" value="false"/> <property name="targetObject"> <ref bean="taskJob"/> </property> <property name="targetMethod"> <value>execute</value> </property> </bean> <!-- 调度触发器 --> <bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="name" value="work_default_name"/> <property name="group" value="work_default"/> <property name="jobDetail"> <ref bean="jobDetail" /> </property> <property name="cronExpression"> <value>0/5 * * * * ?</value> </property> </bean> <!-- 调度工厂 --> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="myTrigger"/> </list> </property> </bean>
但有时候会经常改变任务时间或者暂停任务,这时需要用到动态的任务。
动态任务的时间可以保存在数据库,需要改变的时候重新从数据库读取,也可以临时写入。
通过注入schedulerFactoryBean,利用它来进行对任务的动态操作。
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
然后需要初始化任务,代码中ScheduleJob就是储存任务信息的一个自定义对象。在初始化方法后面给出类代码
public void initCheduler() throws SchedulerException { //schedulerFactoryBean 由spring创建注入 Scheduler scheduler = schedulerFactoryBean.getScheduler(); //这里获取任务信息数据 List<ScheduleJob> jobList = this.getAllJob(); for (ScheduleJob job : jobList) { TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup()); //获取trigger,即在spring配置文件中定义的 bean id="myTrigger" CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //不存在,创建一个 if (null == trigger) { JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(job.getJobName(), job.getJobGroup()).build(); jobDetail.getJobDataMap().put("scheduleJob", job); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); //按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup()); scheduler.triggerJob(jobKey); } else { // Trigger已存在,那么更新相应的定时设置 //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); //按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); //按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } } }
public class ScheduleJob extends BaseEntity{ /** 任务名称 */ private String jobName; /** 任务分组 */ private String jobGroup; /** 任务状态 0禁用 1启用 2删除*/ private String jobStatus; /** 任务运行时间表达式 */ private String cronExpression; /** 任务描述 */ private String descb; public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public String getJobStatus() { return jobStatus; } public void setJobStatus(String jobStatus) { this.jobStatus = jobStatus; } public String getCronExpression() { return cronExpression; } public void setCronExpression(String cronExpression) { this.cronExpression = cronExpression; } public String getDescb() { return descb; } public void setDescb(String desc) { this.descb = desc; } }
此时任务已经初始化,但是还没有执行任务方法的地方,下面给出
public class QuartzJobFactory implements Job { static VideoSerice videoSerice; static{ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:config/applicationContext.xml"); videoSerice=(VideoSerice)context.getBean("videoServiceImpl"); } @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("任务成功运行"); ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get("scheduleJob"); System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]"); videoSerice.getLottery(); } }
当有任务到达执行时间时会进入execute方法,此时context里面包含了任务信息。根据不同的任务信息我们执行不同的任务。
最后一般操作任务的方法
暂停任务
Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.pauseJob(jobKey);
恢复任务
Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.resumeJob(jobKey);
删除任务
Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey);
立即运行任务(只会执行一次)
Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey =JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.triggerJob(jobKey);
获取任务此时状态
trigger各状态说明:
None:Trigger已经完成,且不会在执行,或者找不到该触发器,或者Trigger已经被删除 NORMAL:正常状态 PAUSED:暂停状态 COMPLETE:触发器完成,但是任务可能还正在执行中 BLOCKED:线程阻塞状态 ERROR:出现错误
Scheduler scheduler = schedulerFactoryBean.getScheduler(); 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.setDesc("触发器:" + 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); } }