应用场景
给定时间执行任务(在一个确定的天指定,月的哪天,年的哪天…) 或者 重复执行 任务(某个时间重复执行,重复执行直到某个时间,无限重复, 稍后的某个时间重复执行…)
例如:
1. 初始化一个订单后,两个小时候来检查订单状态,如果订单未被处理,触发一个警告,订单状态改为等待
2. 计划表里列一个任务 在每个工作日的11:30 把数据库里的数据同步到一个xml文件中
3. 提供提醒服务
Job 执行
- jobs是任何实现了Job Interface 的java类,为你的工作的执行留下了无限的可能 (execute方法中实现你的逻辑代码,注意JobExecutionContext是传递过来的参数)
- Job 类可以被Quartz或 你的 项目框架实例化。灵活
- 当trigger触发后,scheduler通知0个或者多个java Objects,以及实现JobListener和TriggerListener 接口的,Listener 可以在 job执行之后触发
Executed - Jobs完成后,返回JobCompletionCode 表明 scheduler的成功,JobCompletionCode 也同样可以指导Scheduler 的行为。给予结果的成功失败,比如立即执行Job
功能代码
写之前要先把quartz.jar 和 quartz-job.jar导入项目中
常用的方法可以用static关键字导入
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.DateBuilder.futureDate;
import static org.quartz.CronScheduleBuilder.cronSchedule;
job,trigger 加入schedule 并启动
Date startTime = DateBuilder.nextGivenSecondDate(null, 10);
JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1").build() ;
//或者可以将里面的simpleSchedule 换成cronSchedule("0 0 10 ? * * *")
trigger = newTrigger().withIdentity("trigger2", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)).build();
//job可以不依赖trigger,立即执行 sched.scheduleJob(job,null);
ft = sched.scheduleJob(job, trigger);
sched.start();
获取供执行了多少个job
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
异常处理
JobExecutionException e2 = new JobExecutionException();
e2.setRefireImmediately(true); 立即运行
//e2.setUnscheduleAllTriggers(true);不运行了
//throw e2;
中断job
sched.interrupt(job.getKey());
日历
AnnualCalendar holidays = new AnnualCalendar();
Calendar fourthOfJuly = new GregorianCalendar(2005, 6, 4);
holidays.setDayExcluded(fourthOfJuly, true);
sched.addCalendar("holidays", holidays, false, false);
SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(runDate)
.withSchedule(simpleSchedule().withIntervalInHours(1).repeatForever()).modifiedByCalendar("holidays").build();
监听 1.监听类实现JobListener接口,jobWasExecuted,方法是监听执行后执行的代码
JobListener jobListener = new Job1Listener();
Matcher<JobKey> matcher = KeyMatcher.keyEquals(job.getKey());
sched.getListenerManager().addJobListener(jobListener, matcher);
trigger可以设置监听等级
withPriority
使用插件:配置文件来生成job和trigger
关键点:
- simpleTrigger vs cronTrigger
simpleTrigger适用于隔多久执行,执行多少次这种,cronTrigger 适用于按日历上的来执行,实际应用中cronTrigger更常用。 - cronTrigger 表达式的用法
表达式中 按顺序依次表示: “秒 分 时 day-of-month month day-of-week year” —注意取值范围 :秒分 是0-59 ,时 0-23,Day-of-Month 1-31 ,month 0-11或者 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC, day-of-week 1-7或者SUN, MON, TUE, WED, THU, FRI and SAT. - 线程池的个数
线程池的个数给5个就够了,可以保证100个job了,因为job都比较快执行的,并且都不同一个时间执行,人家有个人如果给了10 15 100个的是人家有数以千trigger
原则就是越小越好,足够你用 - JTA的使用
如果需要所有的job 都加上事物,在配置文件里加上 org.quartz.scheduler.wrapJobExecutionInUserTransaction = true
如果想单个job加事物, 在 类前面加上注解 @ExecuteInJTATransaction - 配置文件
quartz.properties
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: TestScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler.skipUpdateCheck: true
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 12
org.quartz.threadPool.threadPriority: 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold: 60000
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
#org.quartz.jobStore.useProperties: false
#org.quartz.jobStore.dataSource: myDS
#org.quartz.jobStore.tablePrefix: QRTZ_
#org.quartz.jobStore.isClustered: false
#============================================================================
# Configure Datasources
#============================================================================
#org.quartz.dataSource.myDS.driver: org.postgresql.Driver
#org.quartz.dataSource.myDS.URL: jdbc:postgresql://localhost/ErpDB7jia2
#org.quartz.dataSource.myDS.user:erp7jia2
#org.quartz.dataSource.myDS.password:erp7jia2
#org.quartz.dataSource.myDS.maxConnections: 5
#============================================================================
# Configure Plugins
#============================================================================
#org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin
#org.quartz.plugin.jobInitializer.class: org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
#org.quartz.plugin.jobInitializer.fileNames: quartz_data.xml
#org.quartz.plugin.jobInitializer.failOnFileNotFound: true
#org.quartz.plugin.jobInitializer.scanInterval: 120
#org.quartz.plugin.jobInitializer.wrapInUserTransaction: false
quart_data.xml
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
version="1.8">
<pre-processing-commands>
<delete-jobs-in-group>*</delete-jobs-in-group> <!-- clear all jobs in scheduler -->
<delete-triggers-in-group>*</delete-triggers-in-group> <!-- clear all triggers in scheduler -->
</pre-processing-commands>
<processing-directives>
<!-- if there are any jobs/trigger in scheduler of same name (as in this file), overwrite them -->
<overwrite-existing-data>true</overwrite-existing-data>
<!-- if there are any jobs/trigger in scheduler of same name (as in this file), and over-write is false, ignore them rather then generating an error -->
<ignore-duplicates>false</ignore-duplicates>
</processing-directives>
<schedule>
<job>
<name>job11</name>
<job-class>org.quartz.example10.SimpleJob</job-class>
<durability>true</durability>
<recover>false</recover>
</job>
<trigger>
<simple>
<name>trigger11</name>
<job-name>job11</job-name>
<repeat-count>3</repeat-count>
<repeat-interval>3000</repeat-interval>
</simple>
</trigger>
<job>
<name>job22</name>
<job-class>org.quartz.example10.SimpleJob</job-class>
<durability>true</durability>
<recover>false</recover>
</job>
<trigger>
<simple>
<name>trigger22</name>
<job-name>job22</job-name>
<repeat-count>2</repeat-count>
<repeat-interval>1000</repeat-interval>
</simple>
</trigger>
</schedule>
</job-scheduling-data>