quartz基本使用

来源:互联网 发布:nrf24l01与单片机连接 编辑:程序博客网 时间:2024/06/08 04:39

quartz的任务调度功能比JDK自带的Timer强大得多,有必要学习并致用,在此记录一下...


quartz的jar包在官网可以下载到,百度/谷歌:quartz

maven依赖(可以在maven repository找到绝大多数jar的maven依赖):

<dependency>    <groupId>org.quartz-scheduler</groupId>    <artifactId>quartz</artifactId>    <version>2.2.2</version></dependency>


Job接口:只有一个execute方法,类似TimerTask的run方法,里面编写业务逻辑,调用完成后job对象会被销毁


jobDetail是一个包含多个属性的job细节类,用来设置jobClass、name、group、jobDataMap、

其中name和group都是某一个job的标识,JobKey类就包含了这2个属性,

jobClass属性对应我们自己创建的实现了job接口的类,用jobDetail的getKey方法来获取。

jobDataMap是Job和Trigger都有的一个属性,用来存放属性,比如持有别的类的引用,我们需要

把该对象存入HelloJob对象的jobDataMap中,不能直接当作HelloJob.class的属性。


JobExecutionContext:当schedule调用一个job,就会把JobExecutionContext传递到该job的execute方法中,

方便我们获取quartz运行时环境和该job本身的属性,比如获取jobDataMap。
context.getJobDetail().getKey();

context.getJobDetail().getJobDataMap();

context.getTrigger().getKey();

usingJobData(key, value);

最常用的触发器:SimpleTrigger(类似Timer)、CronTrigger

触发器也有name和group属性,以及存放其它自定义属性的jobDataMap

trigger与job的关系是:n对1,即同一个job可以被多个触发器使用

cronTrigger是我们使用quartz的主要原因,我们可以传一个表达式给触发器,该表达式与linux的crontab一样,

它提供了基于日历的、更精细的时间安排,具备jdk自带的timer无法实现的功能。


Cron表达式是由7个表达式组成的字符串

格式:秒 分 时 日 月 周 年






注意:

1.LW一起使用表示最后一个工作日

2.周字段不区分大小写,MON和mon一样

3.利用工具在线生成cron表达式,百度cron在线生成即可

Schedule 所有调度器实例都由工厂模式产生,比如StdScheduleFactory(常用)和DirectScheduleFactory

scheduler的主要函数:

Date scheduleJob()  // 绑定触发器和任务

void start()  // 启动调度器线程

void standby()  // 挂起调度器线程

void shutdown()  // 关闭调度器线程


3个核心组件的关系图

                                         


以下是基于HelloJob绑定到SimpleTrigger和CronTrigger的2个例子:

package quartzTest;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;/** * writer: holien * Time: 2017-07-29 21:55 * Intent: 实现了Job接口的job类,业务逻辑写在execute方法里 */public class HelloJob implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.out.println("job has executed");    }}
package quartzTest;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import java.util.Date;/** * writer: holien * Time: 2017-07-29 22:07 * Intent: 使用simpleTrigger的示例 */public class SimpleTriggerTest {    public static void main(String[] args) throws Exception {        JobKey jobKey1 = new JobKey("job1", "group1");        JobDetail jobDetail = JobBuilder                .newJob(HelloJob.class)                .withIdentity(jobKey1)                .build();        // 创建触发器的开始时间和结束时间,该触发器的执行时间为6秒        Date startTime = new Date();        Date endTime = new Date();        endTime.setTime(endTime.getTime() + 6000);        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("trigger1")                .startAt(startTime)  //触发时间                .endAt(endTime)  //结束时间                .withSchedule(                        SimpleScheduleBuilder.simpleSchedule()                        .withIntervalInSeconds(2)  //每2秒执行一次                        .withRepeatCount(5))  //由于执行时间只有6秒,所以只会执行3次                .build();        Scheduler scheduler = new StdSchedulerFactory().getScheduler();        scheduler.start();  //启动scheduler调度器线程        scheduler.scheduleJob(jobDetail, trigger);//        scheduler.shutdown(true);  // true:等待任务执行完再关闭;false:直接关闭    }}
package quartzTest;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import org.quartz.impl.matchers.KeyMatcher;/** * writer: holien * Time: 2017-07-29 21:17 * Intent: 使用cronTrigger的示例 */public class CronTriggerTest {    public static void main(String[] args) throws Exception {        JobKey jobKey1 = new JobKey("job1", "group1");        JobDetail jobDetail = JobBuilder                .newJob(HelloJob.class)                .withIdentity(jobKey1)                .build();        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("trigger1")                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))                .build();        Scheduler scheduler = new StdSchedulerFactory().getScheduler();        scheduler.start();        scheduler.scheduleJob(jobDetail, trigger);        // 添加监听器        scheduler.getListenerManager().addJobListener(                new HelloJobListener(), KeyMatcher.keyEquals(jobKey1));    }}

Job、Trigger、Schedule都有对应的监听器,以下用Job的监听器来展示一下

jobListener监听器用来监听一个job,提供了jobToBeExecuted、jobExecutionVetoed、jobWasExecuted

3个方法,分别对应job执行前、Job即将被执行,但又被 TriggerListener否决时执行、job执行后。

还有一个比较重要的,设置监听器的名字,也就是我们要重写getName方法,返回一个自定义的名称

以下是用来监听HelloJob的监听器类:

package quartzTest;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.JobListener;/** * writer: holien * Time: 2017-07-30 12:00 * Intent: */public class HelloJobListener implements JobListener {    // 必须为监听器设置一个名字,否则会报错    @Override    public String getName() {        return "HelloJobListener";    }    // 每次job执行之前执行此方法    @Override    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {        System.out.println("job is to be executed");    }    // 每次Job即将被执行,但又被TriggerListener否决时执行    @Override    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {        System.out.println("job is canceled");    }    // 每次job执行之后执行此方法    @Override    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {        System.out.println("job has been canceled");    }}

默认的quartz.properties


文件位于org.quartz包下,我们可以复制一份,放在项目的根目录下,再根据自己的需要修改它里面的属性,

这样项目运行就会优先加载我们自定义的quartz.properties文件,否则加载quartz jar包中自带的。

instanceName:给调度器命名,可以按照功能来命名,比如我们一个quartz集群是为一个功能服务的,

那么调度器的name根据该功能命名,多个调度器取一样的名称

instanceId:指定调度器的唯一id,可以设置AUTO自动生成

此文件还可以配置线程池的信息,还有插件信息


点我跳到quartz整合spring学习笔记