文章目录

  • 概述
  • JobDataMap
  • Xml 配置方式的值的传递
  • Quartz官方示例
  • Job的状态与并发
  • 其它属性
  • JobExecutionException
  • 示例源码

概述

我们在Quartz-Job 详解中,讲解了纯Quartz的参数传递,这里我们将通过与Spring结合的方式再次讲解一下Quartz中的参数传递。


JobDataMap

JobDataMap可用于保存任何数量的(可序列化的)数据对象,我们希望在执行时可以将其提供给作业实例。JobDataMap是Java Map接口的一个实现,并且有一些用于存储和检索原始类型的数据的方便方法。

我们来温习下纯Quartz的写法

// 具体任务 JobDetail
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("jobSays", "Hello World!").usingJobData("myFloatValue", 3.141f).build();

HelloJob如下

/*** 具体执行的任务*/
public class HelloJob implements Job {@Overridepublic 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.out.println("Instance " + key + " of DumbJob says: " + jobSays + ", and val is: " + myFloatValue);}
}

运行结果

Instance group1.job1 of DumbJob says: Hello World!, and val is: 3.141
Instance group1.job1 of DumbJob says: Hello World!, and val is: 3.141

如果在Job类中定义与JobDataMap中键值一致的set和get方法,那么Quartz会自动将这些属性注入。如:

// 具体任务 JobDetail
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("name", "artisan").usingJobData("age", 24).build();

HelloJob

import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 具体执行的任务*/
public class HelloJob implements Job {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {JobKey key = context.getJobDetail().getKey();System.out.println("Instance " + key + ",姓名:" + name + ",年龄:" + age);}
}

运行结果

Instance group1.job1,姓名:artisan,年龄:24
Instance group1.job1,姓名:artisan,年龄:24
Instance group1.job1,姓名:artisan,年龄:24

另外Trigger中也可以设置JobDataMap属性,这是为了在多个Trigger中使用相同的Job。

JobExecutionContext 将会合并JobDetail与Trigger的JobDataMap,如果其中属性名相同,后者将覆盖前者。

可以使用JobExecutionContext.getMergedJobDataMap()方法来获取合并后的JobDataMap。


Xml 配置方式的值的传递

在spring中,如果HelloJob的方法有参数,那么需要指定一些设定才可以,否则会在运行时有NoSuchMethodException异常发生。

简单示例

public class HelloJob {public void execute(String args){System.out.println("------ " + args + "------ ");}
}

xml配置

<!-- 配置JobDetail -->
<bean id="springQtzJobMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><!-- 执行目标job --><property name="targetObject" ref="helloJob"></property><!-- 要执行的方法 --><property name="targetMethod" value="execute"></property><!-- 设置参数--><property name="arguments" value="artisan"></property>
</bean>

增加一个arguments的变量,设置一个value即可,如果你点进去观察源代码,会发现,它其实是一个 Object[] 类型的参数

执行结果

------ artisan------
------ artisan------

如果你想传递2个参数,示例如下

public void execute(String name, int age) {System.out.println("------ " + name + ":" + age + "------ ");
}
<!-- 设置参数-->
<property name="arguments"><list><value>artisan</value><value>23</value></list>
</property>

当然,我们也可以传递Map,Set,JavaBean对象等等,这里只是抛砖引玉。


Quartz官方示例

第4个案例

http://www.quartz-scheduler.org/documentation/quartz-2.2.x/examples/Example4.html

示例演示了静态变量和非静态变量的修改,只有静态成员才能改变

package com.xgj.quartz.quartzItself.jobDataMapOfficalDemo;import java.text.SimpleDateFormat;
import java.util.Date;import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.PersistJobDataAfterExecution;@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class ColorJob implements Job {public static final String FAVORITE_COLOR = "favorite color";public static final String EXECUTION_COUNT = "count";// 由于Quartz会在每次执行时重新实例化一个类,因此成员非静态成员变量不能用于维护状态!private int _counter = 1;public void execute(JobExecutionContext context)throws JobExecutionException {JobKey jobKey = context.getJobDetail().getKey();JobDataMap data = context.getJobDetail().getJobDataMap();String favoriteColor = data.getString(FAVORITE_COLOR);int count = data.getInt(EXECUTION_COUNT);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");System.out.println("任务Key: " + jobKey + " ,执行时间:  "+ sdf.format(new Date()) + "\n" + "  传递参数(favorite color): "+ favoriteColor + "\n" + "  传递参数(count):  " + count + "\n"+ "  ColorJob非静态变量值: " + _counter + "\n");count++;data.put(EXECUTION_COUNT, count);data.put(FAVORITE_COLOR, "黄色");_counter++;}}
package com.xgj.quartz.quartzItself.jobDataMapOfficalDemo;import static org.quartz.DateBuilder.nextGivenSecondDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;import java.text.SimpleDateFormat;
import java.util.Date;import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class JobStateExample {public void run() throws Exception {Logger log = LoggerFactory.getLogger(JobStateExample.class);SchedulerFactory sf = new StdSchedulerFactory();Scheduler sched = sf.getScheduler();// 在当前时间10秒后运行Date startTime = nextGivenSecondDate(null, 10);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");// 通过过JobDetail封装ColorJob,同时指定Job在Scheduler中所属组及名称,这里,组名为group1,而名称为job1。JobDetail job1 = newJob(ColorJob.class).withIdentity("job1", "group1").build();// 创建一个SimpleTrigger实例,指定该Trigger在Scheduler中所属组及名称。// 接着设置调度的时间规则.当前时间10秒后运行,每10秒运行一次,共运行4次SimpleTrigger trigger1 = newTrigger().withIdentity("trigger1", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(4)).build();// 将参数传递入任务的数据Map中job1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "绿色");job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);// 注册并进行调度Date scheduleTime1 = sched.scheduleJob(job1, trigger1);log.error("任务key: " + job1.getKey() + ",执行运行时间: "+ sdf.format(scheduleTime1) + ",触发器重复执行次数: "+ trigger1.getRepeatCount() + ",触发器执行时间: "+ trigger1.getRepeatInterval() / 1000 + "秒");// 第二个任务JobDetail job2 = newJob(ColorJob.class).withIdentity("job2", "group1").build();SimpleTrigger trigger2 = newTrigger().withIdentity("trigger2", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(4)).build();// 传递数据job2.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "红色");job2.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);Date scheduleTime2 = sched.scheduleJob(job2, trigger2);log.error("第二个任务key: " + job2.getKey().toString() + ",执行运行时间: "+ sdf.format(scheduleTime2) + ",触发器重复执行次数: "+ trigger2.getRepeatCount() + ",触发器执行时间: "+ trigger2.getRepeatInterval() / 1000 + "秒");// 调度器启动sched.start();try {Thread.sleep(60L * 1000L);} catch (Exception e) {}// 调度器停止sched.shutdown(true);SchedulerMetaData metaData = sched.getMetaData();log.error("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");}public static void main(String[] args) throws Exception {JobStateExample example = new JobStateExample();example.run();}}

执行结果如下

INFO  StdSchedulerFactory - Using default implementation for ThreadExecutor
INFO  SimpleThreadPool - Job execution threads will use class loader of thread: main
INFO  SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
INFO  QuartzScheduler - Quartz Scheduler v.2.2.3 created.
INFO  RAMJobStore - RAMJobStore initialized.
INFO  QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.2.3) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.NOT STARTED.Currently in standby mode.Number of jobs executed: 0Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.INFO  StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
INFO  StdSchedulerFactory - Quartz scheduler version: 2.2.3
ERROR JobStateExample - 任务key: group1.job1,执行运行时间: 2017-11-13 10:29:40,触发器重复执行次数: 4,触发器执行时间: 10秒
ERROR JobStateExample - 第二个任务key: group1.job2,执行运行时间: 2017-11-13 10:29:40,触发器重复执行次数: 4,触发器执行时间: 10秒
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
任务Key: group1.job2 ,执行时间:  2017-11-13 10:29:40传递参数(favorite color): 红色传递参数(count):  1ColorJob非静态变量值: 1任务Key: group1.job1 ,执行时间:  2017-11-13 10:29:40传递参数(favorite color): 绿色传递参数(count):  1ColorJob非静态变量值: 1任务Key: group1.job1 ,执行时间:  2017-11-13 10:29:50传递参数(favorite color): 黄色传递参数(count):  2ColorJob非静态变量值: 1任务Key: group1.job2 ,执行时间:  2017-11-13 10:29:50传递参数(favorite color): 黄色传递参数(count):  2ColorJob非静态变量值: 1任务Key: group1.job1 ,执行时间:  2017-11-13 10:30:00传递参数(favorite color): 黄色传递参数(count):  3ColorJob非静态变量值: 1任务Key: group1.job2 ,执行时间:  2017-11-13 10:30:00传递参数(favorite color): 黄色传递参数(count):  3ColorJob非静态变量值: 1任务Key: group1.job1 ,执行时间:  2017-11-13 10:30:10传递参数(favorite color): 黄色传递参数(count):  4ColorJob非静态变量值: 1任务Key: group1.job2 ,执行时间:  2017-11-13 10:30:10传递参数(favorite color): 黄色传递参数(count):  4ColorJob非静态变量值: 1任务Key: group1.job1 ,执行时间:  2017-11-13 10:30:20传递参数(favorite color): 黄色传递参数(count):  5ColorJob非静态变量值: 1任务Key: group1.job2 ,执行时间:  2017-11-13 10:30:20传递参数(favorite color): 黄色传递参数(count):  5ColorJob非静态变量值: 1INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.
ERROR JobStateExample - Executed 10 jobs.

Job的状态与并发

@DisallowConcurrentExecution:同一时间将只有一个Job实例被执行。

@PersistJobDataAfterExecution:在Job被执行结束后,将会更新JobDataMap,这样下次Job执行后就会使用新的值而不是初始值。 上面的示例中,如果不用此注解,成员变量的值下次调用也不会有改变。

如果使用@PersistJobDataAfterExecution注解,推荐也使用@DisallowConcurrentExecution注解,这是为了避免并发问题导致数据紊乱。


其它属性

Durability,持久性;如果Job是非持久性的,一旦没有Trigger与其相关联,它就会从Scheduler中被删除。也就是说Job的生命周期和其Trigger是关联的。

RequestsRecovery,如果为true,那么在Scheduler异常中止或者系统异常关闭后,当Scheduler重启后,Job会被重新执行。


JobExecutionException

execute()方法只允许抛出JobExecutionException异常


示例源码

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

Quartz-JobDataMap 参数传递相关推荐

  1. 【Quartz】深入Job、JobDetail、JobDataMap、Trigger

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. Quartz API核心接口有: Scheduler – 与scheduler交互的主要API: J ...

  2. 第四十章:基于SpringBoot Quartz完成定时任务分布式多节点负载持久化

    在上一章[第三十九章:基于SpringBoot & Quartz完成定时任务分布式单节点持久化]中我们已经完成了任务的持久化,当我们创建一个任务时任务会被quartz定时任务框架自动持久化到数 ...

  3. Quartz 框架快速入门(一)

    创建一个 Java 工程,引入几个 JAR 到工程中才能成功构建它们.首先,你需要 Quartz 的二进制版本,包的名字是 quartz-<version>.jar.Quartz 还需要几 ...

  4. Hello Quartz (第一部分)

    多数读者都较容易从一个简明扼要的例子中明白一个东西.作为写作者,要注意避免把一章的内容精简地几乎什么都没了:作为读者呢,需要有耐心并且要进一步相信其后相关的章节应该去阅读,尽管这个例子看起来是如此之简 ...

  5. Java基于Quartz的定时任务调度服务(一)

    Quartz的基本用法 一 Quartz的简单介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现,一个优秀的开源调度框架,其特点是:强大的 ...

  6. quartz mysql 初始化_quartz2.3.0(十五)执行、暂停、继续执行、清除,花式操作数据库中持久化的job任务...

    前提准备: 先在数据库中建立quartz需要的11张表(我这里用的是Oracle数据库),根据不同的数据库quartz分别提供了不同的初始化sql文件,sql文件路径在 quartz-2.3.0-SN ...

  7. Quartz应用----发送邮件工作调度Java(转)

    Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.下面介绍在J2SE中应用的邮件发送工作调度程序.            Quartz要运行起来,最简单需 ...

  8. SpringBoot与quartz框架实现分布式定时任务

    前言 quartz的分布式调度策略是以数据库为边界资源的一种异步策略.各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性. 在quartz的集群解决方案里有张表scheduler_loc ...

  9. 【原创】Quartz代码详解

    阅读目录 简单介绍 章节1:Quartz简单实例 章节2:Job.JobDetail.JobBuilder 章节3:Trigger.TriggerBuilder 章节4:Scheduler 章节5:J ...

最新文章

  1. java学习--抽象类与接口
  2. Eclipse使用EGit管理git@OSC项目
  3. python基本语法总结-Python基本语法总结(三) 常用内置函数
  4. senseFly为eBee农用无人机装备多谱段传感器
  5. IAR stm8 调试时无法看到局部变量解决
  6. LeetCode第 227 场周赛题解
  7. cad在线转低版本_为什么别人CAD绘图总是比你快?因为他早就偷偷掌握了这几个技巧...
  8. 常用的计算机组装工具有,计算机组装维护与常用工具软件考试含答案
  9. POJ3764 The xor-longest Path
  10. Java 数组的三种创建方法
  11. Microsoft SQL Server 2008R2企业版64位(带密钥)
  12. Acwing 187. 导弹防御系统
  13. uni真机showToast不显示
  14. [ecshop 资料] ecshop 安装须知 - 支付插件的问题 。。ectouch 小京东
  15. IDEA中Maven项目莫名其妙出现很多飘红
  16. 特斯拉第二季度电动汽车销量下降近 18%
  17. 收集一些好用的搜索引擎
  18. TensorFlow-11-策略网络
  19. 腾讯轻量云服务器控制台详细介绍及建站操作图文教程
  20. Kubernetes零基础快速入门!初学者必看!

热门文章

  1. sql array 数组基本用法(二)
  2. 对比学习系列论文SDCLR(一)-Self-Damaging Contrastive Learning论文的概括
  3. NTU课程笔记 mas714复习:例题
  4. R语言应用实战系列(一)-基于R对QQ群聊天记录数据分析
  5. MATLAB实战系列(五)-模拟退火(SA)算法求解旅行商 (TSP)问题MATLAB代码讲解
  6. Tableau必知必会之妙用Fixed函数聚合分析维度
  7. MapReduce编程实战之“调试”
  8. yy自动语音接待机器人_智能语音机器人落地产品有哪些?
  9. jupyter notebook中忽略所有警告,让页面更整洁
  10. Part1_2 python注释,标准输出,if(else)语句,while语句