
- 外文名
- quartz
- 最新版本
- Quartz 2.3.2
- 类 别
- 开源项目
- 中文名
- 扩特兹公式
- 解 释
- 由java编写的开源作业调度框架
-
Quartz
2017-12-06 09:11:27这里以quartz-2.2.3为例 1.上官网下载quartz的完整版,quartz-2.2.3-distribution.tar,里面包含源代码,官方Demo,Java Doc,所需的Jar包,JDBCStore数据库等文件,下载完毕,将lib文件下的jar包复制到项目中 2....这里以quartz-2.2.3为例
1.上官网下载quartz的完整版,quartz-2.2.3-distribution.tar,里面包含源代码,官方Demo,Java Doc,所需的Jar包,JDBCStore数据库等文件,下载完毕,将lib文件下的jar包复制到项目中
2.quartz主要有三个概念
(1)任务调度器Scheduler
①
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
②
Scheduler schedule = StdSchedulerFactory.getDefaultScheduler();(2)任务触发器Trigger
Trigger tri = TriggerBuilder.newTrigger().build;
(3)任务Job
JobBuilder.newJob(MyJob.class).build();
其他:
Cron表达式:
格式:秒 分 时 日 月 星期几 年(可选)
1:?只能用在日或星期几的域上
2:分隔符[",","-","/","*"];eg:在分钟域使用12/15(从12分开始每隔15分钟触发)
3: 星期(1-7)
4:日跟星期的域不能是互斥的,不能同时使用
5:完整的例子:0 15,25,35 9-17 ? * 6 2017-2018 = 2017年和2018年的6月份每天9点到17点分钟刻度为15或25或35时触发
调度器的设置和功能信息
SchedulerMetaData sm = s.getMetaData();
Job参数:
往具体的Job里传递参数
①
JobDataMap jobParam= jobdetail.getJobDataMap();
jobParam.put("","");
Job任务里获取:JobExecutionContext/ctx.getJobDetail().getJobDataMap().get()
②
JobBuilder.usingJobData(),取时同上
③
JobDataMap jobParam = JobExecutionContext/ctx.getMergedJobDataMap()
监听器管理器:
例:给指定key的任务增加监听器
ListenerManager lm= schedule.getListenerManager();
Matcher<JobKey> matcher = KeyMatcher.keyEquals(job.getKey());
lm.addJobListener(new MyListener(),matcher);二:配置文件
quartz有一个默认的配置文件,在quarz包里,如果需要更改配置文件信息,需要将该文件复制一份到src下
如果需要用到数据库存储
#org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#org.quartz.jobStore.tablePrefix: QRTZ_
#org.quartz.jobStore.useProperties: true
#org.quartz.jobStore.dataSource: ds
#org.quartz.dataSource.ds.driver: com.mysql.jdbc.Driver
#org.quartz.dataSource.ds.URL: jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=UTF-8
#org.quartz.dataSource.ds.user: emil
#org.quartz.dataSource.ds.password: 123456
以上部分为开启JDBCStore,其实没啥用,就记录了一下还未跑完的任务,已经跑完的就不知所踪了,如果需要自己记录任务的详细情况,自己动手写吧。#配置一个全局的任务监听器,当然这个也是可以在代码中添加的
org.quartz.jobListener.NAME.class = MyListener
更多详细的配置可以参考官方网站:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/
入门demo:
try { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail jobdetail = JobBuilder.newJob(MyJob.class).withIdentity("任务名字").build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("触发器名字") .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(5).withRepeatCount(3)) .build(); // and start it off scheduler.scheduleJob(jobdetail, trigger); scheduler.start(); } catch (SchedulerException se) { se.printStackTrace(); }
public class MyJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { //通过上下文获取 JobKey jobKey = context.getJobDetail().getKey(); System.out.println("任务id>>>>>>>>>>>>>>>"+jobKey); for(int i=0;i<5;i++) { System.out.println("i am a superman"); } } }
-
quartz
2012-06-04 17:34:56package myschedule.service.quartz; import static myschedule.service.ErrorCode.SCHEDULER_PROBLEM; import static org.quartz.CalendarIntervalScheduleBuilder.calendarIntervalSchedule; import static opackage myschedule.service.quartz; import static myschedule.service.ErrorCode.SCHEDULER_PROBLEM; import static org.quartz.CalendarIntervalScheduleBuilder.calendarIntervalSchedule; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.TriggerBuilder.newTrigger; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import myschedule.service.ErrorCodeException; import org.quartz.Calendar; import org.quartz.CalendarIntervalTrigger; import org.quartz.CronTrigger; import org.quartz.DateBuilder.IntervalUnit; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerMetaData; import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.quartz.TriggerKey; import org.quartz.impl.matchers.GroupMatcher; import org.quartz.spi.MutableTrigger; import org.quartz.spi.OperableTrigger; /** * A template to simplify quartz Scheduler class. It provides some more convenient methods to schedule * jobs and convert Quartz's "checked" SchedulerException into an "unchecked" ErrorCodeException. * * @author Zemian Deng */ public class SchedulerTemplate { protected Scheduler scheduler; public SchedulerTemplate(Scheduler scheduler) { this.scheduler = scheduler; } public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } public Scheduler getScheduler() { return scheduler; } public List<String> getCalendarNames() { try { return scheduler.getCalendarNames(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public boolean isShutdown() { try { return scheduler.isShutdown(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public boolean isInStandbyMode() { try { return scheduler.isInStandbyMode(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public boolean isStarted() { try { return scheduler.isStarted(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public List<JobExecutionContext> getCurrentlyExecutingJobs() { try { List<JobExecutionContext> result = new ArrayList<JobExecutionContext>(); List<?> jobs = scheduler.getCurrentlyExecutingJobs(); for (Object job : jobs) { JobExecutionContext jobec = (JobExecutionContext)job; result.add(jobec); } return result; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public SchedulerMetaData getSchedulerMetaData() { try { return scheduler.getMetaData(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Get all the JobDetails in the scheduler. */ public List<JobDetail> getJobDetails() { try { List<JobDetail> jobs = new ArrayList<JobDetail>(); List<String> groups = scheduler.getJobGroupNames(); for (String group : groups) { Set<JobKey> keys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(group)); for (JobKey key : keys) { JobDetail jobDetail = scheduler.getJobDetail(key); jobs.add(jobDetail); } } return jobs; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Get all the triggers in the scheduler. */ public List<? extends Trigger> getTriggers(JobDetail jobDetail) { try { List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobDetail.getKey()); return triggers; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public JobDetail getJobDetail(String jobName, String group) { try { JobKey key = JobKey.jobKey(jobName, group); return scheduler.getJobDetail(key); } catch (Exception e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public Trigger getTrigger(String triggerName, String group) { try { TriggerKey key = TriggerKey.triggerKey(triggerName, group); return scheduler.getTrigger(key); } catch (Exception e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public Calendar getCalendar(String calName) { try { return scheduler.getCalendar(calName); } catch (Exception e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** * Get a list of next fire time dates up to maxCount time. If next fire time needed * before maxCount, then there should be a null object in the last element of the list. */ public List<Date> getNextFireTimes(Trigger trigger, Date startTime, int maxCount) { // We will clone the original trigger so we may call its triggered() to get a proper fireTime. OperableTrigger clonedTrigger = (OperableTrigger)((OperableTrigger)trigger).clone(); Calendar cal = null; if (clonedTrigger.getNextFireTime() == null) { clonedTrigger.computeFirstFireTime(cal); } List<Date> list = new ArrayList<Date>(); Date nextDate = startTime; int count = 0; while(count++ < maxCount) { nextDate = clonedTrigger.getFireTimeAfter(nextDate); if (nextDate == null) break; list.add(nextDate); clonedTrigger.triggered(cal); } return list; } /** * Get a list of next fire time dates up to maxCount time. If next fire time needed * before maxCount, then there should be a null object in the last element of the list. */ public List<Date> getNextFireTimesWithCalendar(Trigger trigger, Date startTime, int maxCount) { List<Date> dates = getNextFireTimes(trigger, startTime, maxCount); String calName = trigger.getCalendarName(); if (calName == null) { return dates; } // Else check if dates has excluded by calendar or not. Calendar cal = getCalendar(calName); List<Date> result = new ArrayList<Date>(); for (Date dt : dates) { if (cal.isTimeIncluded(dt.getTime())) { result.add(dt); } } return result; } /** Update existing job with newJobDetail and return the old one. */ public JobDetail updateJobDetail(JobDetail newJobDetail) { try { JobDetail oldJob = scheduler.getJobDetail(newJobDetail.getKey()); scheduler.addJob(newJobDetail, true); return oldJob; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Update existing trigger with newTrigger and return the old one. */ public Trigger updateTrigger(Trigger newTrigger) { try { Trigger oldTrigger = scheduler.getTrigger(newTrigger.getKey()); scheduler.rescheduleJob(oldTrigger.getKey(), newTrigger); return oldTrigger; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Add a JobDetail with a trigger schedule when to fire. */ public Date scheduleJob(JobDetail jobDetail, Trigger trigger) { try { Date nextFireTime = scheduler.scheduleJob(jobDetail, trigger); return nextFireTime; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Schedule new trigger to an existing JobDetail. You need to set "trigger.setJobName()". */ public void scheduleJob(Trigger trigger) { try { scheduler.scheduleJob(trigger); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Remove a trigger and its JobDetail if it's not set durable. */ public Trigger uncheduleJob(String triggerName, String triggerGroup) { try { Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(triggerName, triggerGroup)); boolean success = scheduler.unscheduleJob(trigger.getKey()); if (!success) throw new SchedulerException("Failed to unschedule job. Trigger name=" + triggerName + ", group=" + triggerGroup); return trigger; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public void addJob(JobDetail job, boolean replace) { try { scheduler.addJob(job, replace); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Remove a JobDetail and all the triggers associated with it. */ public List<? extends Trigger> deleteJob(String jobName, String group) { try { JobKey key = JobKey.jobKey(jobName, group); List<? extends Trigger> triggers = scheduler.getTriggersOfJob(key); boolean success = scheduler.deleteJob(key); if (!success) throw new SchedulerException("Unable to delete job " + key); return triggers; } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** * Load job scheduling data xml using XMLSchedulingDataProcessor. * @param xml - xml content of job_scheduling_data xml. * @return XMLSchedulingDataProcessor instance will contain all the jobs parse in xml. */ public XmlJobLoader scheduleXmlSchedulingData(String xml) { try { // XmlJobLoader is not only just a loader, but also use to store what's loaded! XmlJobLoader xmlJobLoader = XmlJobLoader.newInstance(); String systemId = XmlJobLoader.XML_SYSTEM_ID; InputStream istream = new ByteArrayInputStream(xml.getBytes()); xmlJobLoader.processStreamAndScheduleJobs(istream, systemId, scheduler); return xmlJobLoader; } catch (Exception e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } /** Run a job immediately with a non-volatile trigger (remove as soon as it's finished.) */ public void runJobNow(String name, String group) { try { JobKey key = JobKey.jobKey(name, group); scheduler.triggerJob(key); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public static JobDetail createJobDetail(String name, Class<? extends Job> jobClass) { return createJobDetail(name, null, true, jobClass, null); } public static JobDetail createJobDetail(String name, String group, boolean durable, Class<? extends Job> jobClass, Map<String, Object> data) { JobDetail jobDetail = newJob(jobClass).withIdentity(name, group).storeDurably(durable).build(); if (data != null) jobDetail.getJobDataMap().putAll(data); return jobDetail; } public static MutableTrigger createCalendarIntervalTrigger( String name, int interval, IntervalUnit intervalUnit) { return createCalendarIntervalTrigger(name, null, interval, intervalUnit, null, null); } public static MutableTrigger createCalendarIntervalTrigger( String name, String group, int interval, IntervalUnit intervalUnit, Date startTime, Date endTime) { if (group == null) group = Scheduler.DEFAULT_GROUP; if (startTime == null) startTime = new Date(); CalendarIntervalTrigger trigger = newTrigger() .withIdentity(name, group) .startAt(startTime).endAt(endTime) .withSchedule(calendarIntervalSchedule().withInterval(interval, intervalUnit)) .build(); return (MutableTrigger)trigger; } public static MutableTrigger createCronTrigger(String name, String cron) { return createCronTrigger(name, null, cron, null, null); } public static MutableTrigger createCronTrigger(String name, String group, String cron, Date startTime, Date endTime) { if (group == null) group = Scheduler.DEFAULT_GROUP; if (startTime == null) startTime = new Date(); try { CronTrigger trigger = newTrigger() .withIdentity(name, group) .startAt(startTime).endAt(endTime) .withSchedule(cronSchedule(cron)) .build(); return (MutableTrigger)trigger; } catch (ParseException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public static MutableTrigger createSimpleTrigger(String name, String group, int repeatTotalCount, long repeatInterval, Date startTime, Date endTime) { if (group == null) group = Scheduler.DEFAULT_GROUP; if (startTime == null) startTime = new Date(); // Quartz's SimpleTrigger's repeatCount is one less than repeatTotalCount, so we need to adjust. int repeatCount = repeatTotalCount - 1; if (repeatTotalCount < 0) repeatCount = SimpleTrigger.REPEAT_INDEFINITELY; SimpleTrigger trigger = newTrigger() .withIdentity(name, group) .startAt(startTime).endAt(endTime) .withSchedule( simpleSchedule() .withRepeatCount(repeatCount) .withIntervalInMilliseconds(repeatInterval)) .build(); return (MutableTrigger)trigger; } public Date scheduleCronJob( String name, String group, String cron, Date startTime, Date endTime, Class<? extends Job> jobClass, Map<String, Object> data) { JobDetail job = createJobDetail(name, group, false, jobClass, data); Trigger trigger = createCronTrigger(name, group, cron, startTime, endTime); return scheduleJob(job, trigger); } public Date scheduleRepeatForeverJob(String name, long repeatInterval, Class<? extends Job> jobClass) { return scheduleRepeatableJob(name, null, null, null, -1, repeatInterval, jobClass, null); } public Date scheduleRepeatableJob(String name, int repeatCount, long repeatInterval, Class<? extends Job> jobClass) { return scheduleRepeatableJob(name, null, null, null, repeatCount, repeatInterval, jobClass, null); } public Date scheduleRepeatableJob( String name, String group, Date startTime, Date endTime, int repeatTotalCount, long repeatInterval, Class<? extends Job> jobClass, Map<String, Object> data) { JobDetail job = createJobDetail(name, group, false, jobClass, data); Trigger trigger = createSimpleTrigger(name, group, repeatTotalCount, repeatInterval, startTime, endTime); return scheduleJob(job, trigger); } public Date scheduleOnetimeJob(String name, Class<? extends Job> jobClass) { return scheduleRepeatableJob(name, 1, 0, jobClass); } public Date scheduleOnetimeJob(String name, String group, Date startTime, Date endTime, Class<? extends Job> jobClass, Map<String, Object> data) { return scheduleRepeatableJob(name, group, startTime, endTime, 1, 0, jobClass, data); } public String getSchedulerName() { try { return scheduler.getSchedulerName(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public String getSchedulerInstanceId() { try { return scheduler.getSchedulerInstanceId(); } catch (SchedulerException e) { throw new ErrorCodeException(SCHEDULER_PROBLEM, e); } } public String getSchedulerNameAndId() { return getSchedulerName() + "_$_" + getSchedulerInstanceId(); } @Override public String toString() { return "QuartzScheduler[" + getSchedulerNameAndId() + "]"; } }
-
Spring+Quartz实现定时任务的配置方法
2019-07-31 19:16:18<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="... xmlns:context="...<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- Scheduler配置 --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="teachingProcessTrigger" /> </list> </property> <property name="quartzProperties"> <props> <prop key="org.quartz.threadPool.threadCount">3</prop> </props> </property> </bean> <!-- Trigger配置 --> <bean id="teachingProcessTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> <ref bean="teachingProcess" /> </property> <property name="cronExpression"> <!-- 每天凌晨0点执行一次 --> <value>0 0 0 * * ?</value> </property> </bean> <!-- JobDetail配置 --> <bean id="teachingProcess" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <!-- hrQuartzServiceImpl是一个业务类,在其他地方声明了bean,这里直接引用就可以 --> <ref bean="hrQuartzServiceImpl" /> </property> <property name="targetMethod"> <!-- hrQuartzServiceImpl类里作为执行入口的方法名 --> <value>doTeachingProcess</value> </property> </bean> </beans>
任务有并行和串行之分,并行是指:一个定时任务,当执行时间到了的时候,立刻执行此任务,不管当前这个任务是否在执行中;串行是指:一个定时任务,当执行时间到了的时候,需要等待当前任务执行完毕,再去执行下一个任务。
quartz框架中可以设置是否允许任务并行:
如果是通过MethodInvokingJobDetailFactoryBean在运行中动态生成的Job,配置的xml文件有个concurrent属性,这个属性的功能是配置此job是否可以并行运行,如果为false则表示不可以并行运行,否则可以并行。如果一个job的业务处理发费的时间超过了job的启动的间隔时间(repeatInterval),这个属性非常有用。如果为false,那么,在这种情况下,当前job还在运行,那么下一个job只能延时运行。如果为true,那么job就会并行运行,配置示例如下:<bean id="jobCompareB2cAndLocal" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject " ref="delegateJob " /> <property name="targetMethod " value="方法名" /> <property name="concurrent " value="false " /> </bean >
如果不配置,默认是true的,就是允许并行。
-
定时任务框架Quartz-(一)Quartz入门与Demo搭建
2018-07-10 13:57:07一、什么是Quartz 什么是Quartz? Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:...一、什么是Quartz
什么是Quartz?
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
- 持久性作业 - 就是保持调度定时的状态;
- 作业管理 - 对调度作业进行有效的管理;
大部分公司都会用到定时任务这个功能。
拿火车票购票来说,当你下单后,后台就会插入一条待支付的task(job),一般是30分钟,超过30min后就会执行这个job,去判断你是否支付,未支付就会取消此次订单;当你支付完成之后,后台拿到支付回调后就会再插入一条待消费的task(job),Job触发日期为火车票上的出发日期,超过这个时间就会执行这个job,判断是否使用等。在我们实际的项目中,当Job过多的时候,肯定不能人工去操作,这时候就需要一个任务调度框架,帮我们自动去执行这些程序。那么该如何实现这个功能呢?
(1)首先我们需要定义实现一个定时功能的接口,我们可以称之为Task(或Job),如定时发送邮件的task(Job),重启机器的task(Job),优惠券到期发送短信提醒的task(Job),实现接口如下:
(2)有了任务之后,还需要一个能够实现触发任务去执行的触发器,触发器Trigger最基本的功能是指定Job的执行时间,执行间隔,运行次数等。
(3)有了Job和Trigger后,怎么样将两者结合起来呢?即怎样指定Trigger去执行指定的Job呢?这时需要一个Schedule,来负责这个功能的实现。
上面三个部分就是Quartz的基本组成部分:
- 调度器:Scheduler
- 任务:JobDetail
- 触发器:Trigger,包括SimpleTrigger和CronTrigger
二、Quartz Demo搭建
下面来利用Quartz搭建一个最基本的Demo。
1、导入依赖的jar包:<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency>
2、新建一个能够打印任意内容的Job:
/** * Created by wanggenshen * Date: on 2018/7/7 16:28. * Description: 打印任意内容 */ public class PrintWordsJob implements Job{ @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date()); System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100)); } }
3、创建Schedule,执行任务:
/** * Created by wanggenshen * Date: on 2018/7/7 16:31. * Description: XXX */ public class MyScheduler { public static void main(String[] args) throws SchedulerException, InterruptedException { // 1、创建调度器Scheduler SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); // 2、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容) JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class) .withIdentity("job1", "group1").build(); // 3、构建Trigger实例,每隔1s执行一次 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1") .startNow()//立即生效 .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(1)//每隔1s执行一次 .repeatForever()).build();//一直执行 //4、执行 scheduler.scheduleJob(jobDetail, trigger); System.out.println("--------scheduler start ! ------------"); scheduler.start(); //睡眠 TimeUnit.MINUTES.sleep(1); scheduler.shutdown(); System.out.println("--------scheduler shutdown ! ------------"); } }
运行程序,可以看到程序每隔1s会打印出内容,且在一分钟后结束:
三、Quartz核心详解
下面就程序中出现的几个参数,看一下Quartz框架中的几个重要参数:
- Job和JobDetail
- JobExecutionContext
- JobDataMap
- Trigger、SimpleTrigger、CronTrigger
(1)Job和JobDetail
Job是Quartz中的一个接口,接口下只有execute方法,在这个方法中编写业务逻辑。
接口中的源码:
JobDetail用来绑定Job,为Job实例提供许多属性:
- name
- group
- jobClass
- jobDataMap
JobDetail绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
为什么设计成JobDetail + Job,不直接使用Job
JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。
这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。(2)JobExecutionContext
JobExecutionContext中包含了Quartz运行时的环境以及Job本身的详细数据信息。
当Schedule调度执行一个Job的时候,就会将JobExecutionContext传递给该Job的execute()中,Job就可以通过JobExecutionContext对象获取信息。
主要信息有:
(3)JobExecutionContext
JobDataMap实现了JDK的Map接口,可以以Key-Value的形式存储数据。
JobDetail、Trigger都可以使用JobDataMap来设置一些参数或信息,
Job执行execute()方法的时候,JobExecutionContext可以获取到JobExecutionContext中的信息:
如:JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class) .usingJobData("jobDetail1", "这个Job用来测试的") .withIdentity("job1", "group1").build(); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1") .usingJobData("trigger1", "这是jobDetail1的trigger") .startNow()//立即生效 .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(1)//每隔1s执行一次 .repeatForever()).build();//一直执行
Job执行的时候,可以获取到这些参数信息:
@Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("jobDetail1")); System.out.println(jobExecutionContext.getTrigger().getJobDataMap().get("trigger1")); String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date()); System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100)); }
(4)Trigger、SimpleTrigger、CronTrigger
- Trigger
Trigger是Quartz的触发器,会去通知Scheduler何时去执行对应Job。
new Trigger().startAt():表示触发器首次被触发的时间; new Trigger().endAt():表示触发器结束触发的时间;
- SimpleTrigger
SimpleTrigger可以实现在一个指定时间段内执行一次作业任务或一个时间段内多次执行作业任务。
下面的程序就实现了程序运行5s后开始执行Job,执行Job 5s后结束执行:
Date startDate = new Date(); startDate.setTime(startDate.getTime() + 5000); Date endDate = new Date(); endDate.setTime(startDate.getTime() + 5000); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1") .usingJobData("trigger1", "这是jobDetail1的trigger") .startNow()//立即生效 .startAt(startDate) .endAt(endDate) .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(1)//每隔1s执行一次 .repeatForever()).build();//一直执行
- CronTrigger
CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的,先了解下Cron表达式:
由7个子表达式组成字符串的,格式如下:[秒] [分] [小时] [日] [月] [周] [年]
Cron表达式的语法比较复杂,
如:* 30 10 ? * 1/5 *
表示(从后往前看)
[指定年份] 的[ 周一到周五][指定月][不指定日][上午10时][30分][指定秒]又如:00 00 00 ? * 10,11,12 1#5 2018
表示2018年10、11、12月的第一周的星期五这一天的0时0分0秒去执行任务。下面是给的一个例子:
可通过在线生成Cron表达式的工具:http://cron.qqe2.com/ 来生成自己想要的表达式。
下面的代码就实现了每周一到周五上午10:30执行定时任务
/** * Created by wanggenshen * Date: on 2018/7/7 20:06. * Description: XXX */ public class MyScheduler2 { public static void main(String[] args) throws SchedulerException, InterruptedException { // 1、创建调度器Scheduler SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); // 2、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容) JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class) .usingJobData("jobDetail1", "这个Job用来测试的") .withIdentity("job1", "group1").build(); // 3、构建Trigger实例,每隔1s执行一次 Date startDate = new Date(); startDate.setTime(startDate.getTime() + 5000); Date endDate = new Date(); endDate.setTime(startDate.getTime() + 5000); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1") .usingJobData("trigger1", "这是jobDetail1的trigger") .startNow()//立即生效 .startAt(startDate) .endAt(endDate) .withSchedule(CronScheduleBuilder.cronSchedule("* 30 10 ? * 1/5 2018")) .build(); //4、执行 scheduler.scheduleJob(jobDetail, cronTrigger); System.out.println("--------scheduler start ! ------------"); scheduler.start(); System.out.println("--------scheduler shutdown ! ------------"); } }
2018/07/07 20:10 in SH.
-
Quartz 入门详解
2017-05-23 14:39:18基本上任何公司都会用到调度这个功能, 比如我们公司需要定期执行调度生成报表, 或者比如博客什么的定时更新之类的,都可以靠Quartz来完成。正如官网所说,小到独立应用大到大型电子商务网站, Quartz都能胜任。... -
Quartz 定时任务调度框架
2020-10-06 19:40:36定时任务调度框架 Quartz 入门案例: 依赖: <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> ... -
精进 Quartz—Quartz大致介绍(一)
2017-02-04 15:13:26Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他... -
精进Quartz—Spring和Quartz集成详解(三)
2017-02-06 11:49:46Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度。下面就对Spring集成Quartz进行简单的介绍和示例讲解!和上一节 Quartz学习——2、简单入门示例Demo 的... -
Quartz简介
2020-11-22 12:38:15文章目录Quartz 是什么What is the Quartz Job Scheduling Library?使用场景特点Quartz 使用的设计模式核心元素SchedulerTriggerCalendarJobDetailJobJobExecutionContext核心元素之间的关系Quartz 类图主要线程数据... -
精进Quartz—Quartz简单入门Demo(二)
2017-02-04 15:55:38要学习Quartz框架,首先大概了解了Quartz的基本知识后,在通过简单的例子入门,一步一个脚印的走下去。 下面介绍Quartz入门的示例,由于Quartz的存储方式分为RAM和JDBC,分别对这两种进行简单的说明。并附上代码! ... -
Spring Quartz & Spring Boot Quartz AutoConfigure
2019-03-31 13:25:08Spring Quartz spring 分别对Quartz的三个方面,Job & JobDetail,Trigger和Scheduler进行了封装,Spring Quartz 和 Spring Scheduling是任务调度的两种方案,两者在使用上完全没有关系,Spring Scheduling使用的... -
quartz quartz-1.8.6 dbTables 建表sql
2013-08-08 18:31:19quartz quartz-1.8.6 dbTables quartz动态任务调度需要的数据库脚本。 -
Quartz概述
2016-09-04 11:42:17Quartz是开源任务调度框架中的翘楚,它提供了强大的 任务调度机制。Quartz允许开发人员灵活的定义触发器的调度时间表,并可对触发器和任务进行关联映射。此外,Quartz提供了调度运行环境的持久化机制,可以保存并... -
quartz定时器
2019-06-27 09:51:18一、关于 Quartz Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。 Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。 ... -
Quartz Cluster
2019-03-31 15:56:05基于数据库JobStore的Quartz Cluster实现 ClusterManager 如果开启cluster的话,ClusterManager线程会运行,参见JobStroeSupport#scheduleStarted(); ClusterCheck这个check是check啥,参看JobStoreSupport#... -
quartz调度问题 没报错也没停止运行 Scheduler class: 'org.quartz.core.QuartzScheduler' - running ...
2020-03-04 13:45:46Scheduler class: ‘org.quartz.core.QuartzScheduler’ - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool ‘org.quartz.simpl.SimpleThreadPool’ - ... -
【Quartz】Quartz存储与持久化-基于quartz.properties的配置
2015-05-07 09:23:17林炳文Evankaka原创作品。... 一、 Quartz存储与持久化 Quartz提供两种基本作业存储...在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。不足之处是缺乏... -
Quartz-异常处理
2017-11-15 13:18:17示例源码概述我们根据官网示例说明Quartz在job执行异常情况时的处理。参考官方原文: http://www.quartz-scheduler.org/documentation/quartz-2.2.x/examples/Example6.html本文涉及3个类: BadJob1.java、 ... -
Quartz报错
2017-11-28 16:21:57Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'org.quartz.simpl.SimpleThreadPoo
-
找最小值
-
C#文件传输、Socket通信、大文件断点续传
-
VS2019谷歌V8引擎8.2版本,编译好的Release版DLL和LIB,和测试demo
-
Optimization Week 10: Gradient Descent
-
DQL语言-子查询
-
TM241等普通PLC实现电子凸轮功能和CNC.pdf
-
VB编写PC与S7-200通讯软件.zip
-
Android-UI-03-图形绘制-Canvas-drawable案列
-
287. 寻找重复数(转换成图论去做,环形链表)
-
MFC开发简单聊天程序
-
单片机完全学习课程全五季套餐
-
Firefox 47.0.1 渗透便携版.zip
-
图论算法软件.zip
-
专利的基础知识与专利申请
-
西门子PLC实例教程777个(密码1234).zip
-
Verilog HDL 语法学习笔记
-
VASP安装教程(centos)
-
8086+8253+8259+8255可设置时间时钟
-
【数据分析-随到随学】Python数据获取
-
纯c实现计算器 支持 +-*/%^