quartz详解2--jobDataMap

1. Job 和 JobDetail

Job接口,只有一个execute()方法。
源码:

package org.quartz;

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

我们开发者只要实现此接口,实现execute方法即可。把我们想做的事情,在execute中执行即可。

/ 1 / Job实例在quartz中的生命周期

每次调度器调度job时,在执行execute方法前都会创建新的job实例。
当调用完成后,关联的job实例会被释放,会GC回收。

/ 2 / JobDetail属性

JobDeailjob实例提供了许多设置属性,存储job实例的状态信息。调度器需要借助jobdetail对象来添加job实例。

属性:

  1. name
  2. group
  3. jobClass
  4. jobDataMap

解析:

JobDetail jobDetail = JobBuilder
                .newJob(PrintJob.class)
                .withIdentity("myjob","group1")
                .build();
System.out.println(jobDetail.getKey().getName());
System.out.println(jobDetail.getKey().getGroup());
System.out.println(jobDetail.getJobClass().getName());

说明:
每个JobDetailTriggernamegroup组成的key

显示信息:

myjob
group1(group不写则默认DEFALT)
cn.whbing.pro.quartz.PrintJob

2. JobExecuteContext

1.当scheduler调用一个job,就会将jobExecuteContext传递给job的execute方法。

2.job能够通过对象访问到quartz运行时候的环境以及job本身的明细数据。


3. jobDataMap

1.在进行任务调度时,jobDataMap存储在jobExecuteContext,非常方便获取。
2.jobDataMap可以用来存储任何可以序列化的数据对象,当job实例对象被执行时,这些参数对象会传递给它。
3.jobDataMap实现了Map接口。


4. 实验

目标:在scheduler中传入jobDataMap,在job中通过jobExecuteContext获取。
方法:在jobSchedulerTrigger上使用链式方法usingDataMap()绑定数据。

具体获取有两种方法:
方法一:在Map中获取
方法二:Job实现类中添加setter方法对应JobDataMap的键值(在初始化job实例时会自动调用setter方法)

/ 1 / 在JobDetailTrigger实例上绑定JobDataMap

 //1.创建JobDetail实例,并与printJob Class绑定
 JobDetail jobDetail = JobBuilder
         .newJob(PrintJob.class)
         .withIdentity("myjob","group1")
         .usingJobData("message","hello myjob1")
         .usingJobData("FloatJobValue",3.14F)
         .build();
 //2.定义Trigger实例,定义该job立即执行,并且每隔两秒重复执行一次,直到永远
 Trigger trigger = TriggerBuilder
         .newTrigger()
         .withIdentity("mytrigger","group1")
         .usingJobData("message","hello mytrigger1")
         .usingJobData("DoubleTriggerValue",5.21D)
         .startNow()...

方法1:通过Map获取

/ 2(A) / 在Job中通过context获取JobDetailTrigger本身信息,及JobDataMap信息

public class PrintJob implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //编写具体的业务逻辑即可
        //打印当前时间及hello
        LocalDateTime timeNow = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd hh:mm:ss");
        System.out.println("execute time:"+formatter.format(timeNow));

        System.out.println("hello!");

        //获取jobDetail和trigger信息
        System.out.println("My job name and group:"
                        +context.getJobDetail().getKey().getName()
                        +","+context.getJobDetail().getKey().getGroup());
        System.out.println("My trigger name and group:"
                        +context.getTrigger().getKey().getName()
                        +","+context.getTrigger().getKey().getGroup());
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        JobDataMap tdataMap = context.getTrigger().getJobDataMap();

        String message = dataMap.getString("message");
        System.out.println(message);
        //trigger和其他字段同理
    }
}

结果:

execute time:2018 07 30 08:04:25
hello!
My job name and group:myjob,group1
My trigger name and group:mytrigger,group1
hello myjob1

/ 2(B) / 在Job中通过context获取getMergedJobDataMap
(需保证jobDetail和Trigger中无重复key)

//通过getMergedJobDataMap获取jobdetail和trigger合并后的信息
JobDataMap data = context.getMergedJobDataMap();
//当有相同的key时,先获取jobdetail中的,trigger中的key会覆盖jobdetail
System.out.println(data.getString("message"));

结果:

hello mytrigger1

方法二:Job实现类中添加setter方法对应JobDataMap的键值
(需保证jobDetail和Trigger中无重复key)

说明:类自动注入(连注解都不需要),将通过反射直接将scheduler中的jobdetailtrigger中的jobDataMap的key,通过setter赋予对应字段(名称要相同)

public class PrintJob implements Job {

    private String message;
    private Float FloatJobValue;
    private Double DoubleTriggerValue;

    getter and setter...
    ...
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
       //直接通过setter后的字段访问
        System.out.println("直接通过字段访问1:"+message);
        System.out.println("直接通过字段访问2:"+FloatJobValue);
        System.out.println("直接通过字段访问3:"+DoubleTriggerValue);
    }

结果:(表明有相同字段时,这时以jobdetail为准)

直接通过字段访问1:hello myjob1
直接通过字段访问2:3.14
直接通过字段访问3:5.21

猜你喜欢

转载自blog.csdn.net/answer100answer/article/details/81290290