三:Job 和 JobDetail 详细介绍

从上面两篇文章看出,Job 的实现很简单,该接口只有一个 execute 方法。这一节我们主要关注以下三点:

  1. Job 特点
  2. Job 的 execute 方法
  3. JobDetail

Job 初窥

首先我们回过头看看 教程一 中的代码片段

JobDetail job = JobBuilder.newJob(HelloJob.class)
                .withIdentity("dummyJobName", "group1").build();

Trigger trigger = TriggerBuilder.newTrigger().withIdentity("dummyTriggerName", "group1")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(5).repeatForever()).build();

sched.scheduleJob(job, trigger);

HelloJob类定义如下

public class HelloJob implements Job {
    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        .format(new Date())+"Hello Quartz!");   
    }

}

可以看到,我们传给 scheduler 一个 JobDetail 实例,因为我们在创建 JobDetail 时,将要执行的 job 的类名传给了 JobDetail,所以 scheduler 就知道了要执行何种类型的 job;

当 scheduler 执行 job 时,在调用其 execute() 方法之前会创建该类的一个新的实例,执行完毕,该实例的饮用就会被丢弃,实例会被垃圾回收。这种执行策略带来的后果就是,job 必须有一个无参的构造函数;另一个是,在 job 类中,不应该定义有状态的数据属性,因为 job 多次执行中,这些属性的值不会保留。

那么如何给 job 实例增加属性或配置呢?如何在 job 多次执行中,跟踪 job 的状态呢?答案就是 JobDataMap

JobDataMap

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

将 job 加入到 scheduler 之前,在构建 JobData 时,可以将数据放入 JobDataMap,如下:

JobDetail job = newJob(DumbJob.class)
      .withIdentity("myJob", "group1") // name "myJob", group "group1"
      .usingJobData("jobSays", "Hello World!")
      .usingJobData("myFloatValue", 3.141f)
      .build();

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

 public class DumbJob implements Job {

    public DumbJob() {
    }

    public void execute(JobExecutionContext context)
        throws JobExecutionException
    {
        JobKey key = context.getJobDetail().getKey();

        JobDataMap dataMap = context.getJobDetail().getJobDataMap();

        String jobSays = dataMap.getString("jobSays");
        float myFloatValue = dataMap.getFloat("myFloatValue");

        System.err.println("Instance " + key + " of DumbJob says: " + jobSays + ", and val is: " + myFloatValue);
    }
}

如果你使用的是持久化存储机制,再决定 JobDataMap 中存放什么数据的时候需要小心,因为 JobDataMap 中存储对象都会被序列化,因此很可能会导致类的版本不一致问题;Java 的标准类型都很安全,如果一斤有一个类的序列化后的实例,某个时候,鄙人修改了该类的定义,此时你需要确保对类的修改没有破坏兼容性;

Job 实例

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

比如,你创建了一个实现 Job 接口的类 “SaleReportJob” 。该 job 需要一个参数(通过 JobDataMap 传入),表示负责该销售报告的销售员名字。因此,你可以创建该 job 的多个实例(JobDetail),比如“SalesReportForJoe”、“SalesReportForMike”。将 “joe”、“mike” 作为 JobDataMap 的数据传给对应的 job 实例。

当一个 tigger 被触发时候,与之关联的 JobDetail 实例会被加载,JobDetail 引用的 job 类通过配置在 Scheduler 上的 JobFactory 进行初始化。默认的 JobFactory 实现,仅仅是调用 job 的 newInstance() 方法,然后尝试调用 JobDataMap 中的 key 的 setter 方法。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值