Quartz的使用(一)

Quartz API核心接口有:
1、Scheduler – 与scheduler交互的主要API;
2、Job – 通过scheduler执行任务,你的任务类需要实现的接口;
3、JobDetail – 定义Job的实例;
4、Trigger – 触发Job的执行;
5、JobBuilder – 定义和创建JobDetail实例的接口
6、TriggerBuilder – 定义和创建Trigger实例的接口

maven中需要引入

   <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.2.1</version>
    </dependency>
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

public void startSchedulerTest() throws SchedulerException{
        //Scheduler在使用之前需要实例化。一般通过SchedulerFactory来创建一个实例。
        SchedulerFactory schedFact=new StdSchedulerFactory();
        Scheduler sched=schedFact.getScheduler();

       //要导入静态包文件
        JobDetail job=newJob(HelloJob.class)
                .withIdentity("myJob","group1")
                .build();

        Trigger trigger=newTrigger()
                .withIdentity("myTrigger","group1")
                .startNow()
                .withSchedule(simpleSchedule()
                .withIntervalInSeconds(40)
                .repeatForever())
                .build();

        sched.scheduleJob(job,trigger);

        //scheduler实例化后,可以启动(start)、暂停(stand-by)、停止(shutdown).
        //scheduler被停止后,除非重新实例化,否则不能重新启动;只有当scheduler启动后,
        // trigger才会被触发(job才会被执行)。即使scheduler处于暂停状态job也不执行,
        sched.start();

        sched.shutdown();

    }

Scheduler的生命期,从SchedulerFactory创建它时开始,到Scheduler调用shutdown()方法时结束;Scheduler被创建后,可以增加、删除和列举Job和Trigger,以及执行其它与调度相关的操作(如暂停Trigger)。但是,Scheduler只有在调用start()方法后,才会真正地触发trigger(即执行job)。

也可以这样获得scheduler实例:

Scheduler scheduler=StdSchedulerFactory.getDefaultScheduler();

Job和Trigger
一个job就是一个实现了Job接口的类,该接口只有一个方法:

public interface Job {
    void execute(JobExecutionContext var1) throws JobExecutionException;
}

当job的一个trigger被触发后,execute()方法会被scheduler的一个工作线程调用;每次当scheduler执行job时,在调用其execute(…)方法之前会创建该类的一个新的实例;执行完毕,对该实例的引用就被丢弃了,实例会被垃圾回收;这就会导致:job必须有一个无参的构造函数(当使用默认的JobFactory时);另一个后果是,在job类中,不应该定义有状态的数据属性,因为在job的多次执行中,这些属性的值不会保留。所以要使用JobDataMap跟踪job的状态。

传递给execute()方法的JobExecutionContext对象中保存着该job运行时的一些信息 ,包括执行job的scheduler的引用,触发job的trigger的引用,JobDetail对象引用,以及一些其它信息。

public void execute(JobExecutionContext context) throws JobExecutionException {
        context.getScheduler();
        context.getJobDetail();
        context.getTrigger();
    }

JobDetail对象是在将job加入scheduler时,由客户端程序(你的程序)创建的。它包含job的各种属性设置,以及用于存储job实例状态信息的JobDataMap。

JobDataMap中可以包含不限量的(序列化的)数据对象,在job实例执行的时候,可以使用其中的数据;JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法。

//在创建JobDetail时,将要执行的job的类名传给了JobDetail,所以scheduler就知道了要执行何种类型的job
JobDetail job=newJob(HelloJob.class)
                .withIdentity("myJob","group1")
                //使用jobDataMap保存job实例状态信息
                .usingJobData("jobSays","Hello world")
                .usingJobData("myFloatValue",3.14f)
                .build();

在job的执行过程中,可以从JobDataMap中取出数据:

public void execute(JobExecutionContext context) throws JobExecutionException {
        JobKey key=context.getJobDetail().getKey();
        JobDataMap dataMap=context.getJobDetail().getJobDataMap();
        String jogSays=dataMap.getString("jobSays");
        float myFloat=dataMap.getFloat("myFloatValue");

        System.out.println("key="+key+" jobSays="+jogSays+"  myFloat="+myFloat);
    }
//结果
key=group1.myJob jobSays=Hello world  myFloat=3.14

如果你在job类中,为JobDataMap中存储的数据的key增加set方法(如在上面示例中,增加setJobSays(String val)方法),那么Quartz的默认JobFactory实现在job被实例化的时候会自动调用这些set方法,这样你就不需要在execute()方法中显式地从map中取数据了。

public class HelloJob implements Job {
    String jobSays;
    float myFloatValue;

    public HelloJob(){}
    public void execute(JobExecutionContext context) throws JobExecutionException {

        JobKey key=context.getJobDetail().getKey();
        System.out.println("key="+key+" jobSays="+jobSays+"  myFloat="+myFloatValue);
    }

    public void setJobSays(String jobSays){
        this.jobSays=jobSays;
    }
    public void setMyFloatValue(float myFloatValue){
        this.myFloatValue=myFloatValue;
    }
}
//结果
key=group1.myJob jobSays=Hello world  myFloat=3.14

context.getMergedJobDataMap()方法返回的JobDataMap,它是JobDetail中的JobDataMap和Trigger中的JobDataMap的并集,但是如果存在相同的数据,则后者会覆盖前者的值

JobDetail job=newJob(HelloJob.class)
                .withIdentity("myJob","group1")
                .usingJobData("jobSays","Hello world")
                .usingJobData("myFloatValue",3.14f)
                .build();

        Trigger trigger=newTrigger()
                .withIdentity("myTrigger","group1")
                .usingJobData("myTrigger","Hello Trigger")
               //存在相同的key,会将之前的值覆盖
                .usingJobData("jobSays","Hello world trigger")
                .startNow()
                .withSchedule(simpleSchedule()
                .withIntervalInSeconds(40)
                .repeatForever())
                .build();

//job中
public void execute(JobExecutionContext context) throws JobExecutionException {

        JobKey key=context.getJobDetail().getKey();

        JobDataMap dataMap=context.getMergedJobDataMap();
        String jogSays=dataMap.getString("jobSays");
        float myFloat=dataMap.getFloat("myFloatValue");
        String myTrigger=dataMap.getString("myTrigger");

        System.out.println("key="+key+" jobSays="+jogSays+"  myFloat="+myFloat+  "  myTrigger="+myTrigger);
 //结果
 key=group1.myJob jobSays=Hello world trigger  myFloat=3.14  myTrigger=Hello Trigger

可以只创建一个job类,然后创建多个与该job关联的JobDetail实例,每一个实例都有自己的属性集和JobDataMap,最后,将所有的实例都加到scheduler中。

      JobDetail job=newJob(HelloJob.class)
                .withIdentity("myJob","group1")
                .usingJobData("jobSays","Hello world")
                .usingJobData("myFloatValue",3.14f)
                .build();

        JobDetail job1=newJob(HelloJob.class)
                .withIdentity("myjob1","group2")
                .usingJobData("name","my job")
                .build();

当一个trigger被触发时,与之关联的JobDetail实例会被加载,JobDetail引用的job类通过配置在Scheduler上的JobFactory进行初始化。默认的JobFactory实现,仅仅是调用job类的newInstance()方法,然后尝试调用JobDataMap中的key的setter方法。你也可以创建自己的JobFactory实现,比如让你的IOC或DI容器可以创建/初始化job实例。

将Job和Trigger注册到Scheduler时,可以为它们设置key,配置其身份属性。Job和Trigger的key(JobKey和TriggerKey)可以用于将Job和Trigger放到不同的分组(group)里,然后基于分组进行操作。同一个分组下的Job或Trigger的名称必须唯一,即一个Job或Trigger的key由名称(name)和分组(group)组成。

参考文章:
http://ifeve.com/quartz-tutorial-job-jobdetail/
https://unmi.cc/quartz-job-scheduling-framework-chinese/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值