quartz基本使用

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学习笔记



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值