没有合适的资源?快使用搜索试试~ 我知道了~
Quartz学习资料(完全).pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 83 浏览量
2021-10-30
04:55:50
上传
评论
收藏 205KB PDF 举报
温馨提示
试读
31页
MATLAB
资源推荐
资源详情
资源评论
Quartz 学习资料(完全)
介绍 Quartz
Quartz 是一个开源的任务调度系统,它能用来调度很多任务的执行。
运行环境
Quartz 能嵌入在其他应用程序里运行。
Quartz 能在一个应用服务器里被实例化 (或 servlet 容器 ), 并且参与 XA 事务
Quartz 能独立运行(通过 JVM) ,或者通过 RMI
Quartz 能被集群实例化
任务调度
当一个指定给任务的触发器发生时 ,任务就被调度执行 . 触发器能被创建为 :
一天的某个时间 (精确到毫秒级 )
一周的某些天
一个月的某些天
一年的某些天
不在一个 Calendar 列出的某些天 (例如工作节假日 )
在一个指定的次数重复
重复到一个指定的时间 /日期
无限重复
在一个间隔内重复
能够给任务指定名称和组名 .触发器也能够指定名称和组名 ,这样可以很好的在调度器里组织
起来 .一个加入到调度器里的任务可以被多个触发器注册。 在 J2EE 环境里, 任务能作为一个
分布式( XA)事务的一部分来执行。
任务执行
任务能够是任何实现 Job 接口的 Java 类。
任务类能够被 Quartz 实例化 ,或者被你的应用框架。
当一个触发器触发时, 调度器会通知实例化了 JobListener 和 TriggerListener 接口的
0 个或者多个 Java 对象 (监听器可以是简单的 Java 对象 , EJBs, 或 JMS 发布者等 ). 在
任务执行后,这些监听器也会被通知。
当任务完成时,他们会返回一个 JobCompletionCode ,这个代码告诉调度器任务执
行成功或者失败 .这个代码 也会指示调度器做一些动作 -例如立即再次执行任务。
任务持久化
Quartz 的设计包含 JobStore 接口,这个接口能被实现来为任务的存储提供不同的机
制。
应用 JDBCJobStore, 所有被配置成“稳定”的任务和触发器能通过 JDBC 存储在关
系数据库里。
应用 RAMJobStore, 所有任务和触发器能被存储在 RAM 里因此不必在程序重起之
间保存 -一个好处就是不必使用数据库。
事务
使用 JobStoreCMT ( JDBCJobStore 的子类),Quartz 能参与 JTA 事务。
Quartz 能管理 JTA 事务 (开始和提交 )在执行任务之间,这样,任务做的事就可以发
生在 JTA 事务里。
集群
Fail-over.
Load balancing.
监听器和插件
通过实现一个或多个监听接口, 应用程序能捕捉调度事件来监控或控制任务 /触发器
的行为。
插件机制可以给 Quartz 增加功能,例如保持任务执行的历史记录,或从一个定义好
的文件里加载任务和触发器。
Quartz 装配了很多插件和监听器。
1.使用 Quartz
在我们用调度器之前,调度器需要实例化。我们用 SchedulerFactory 来实例它。一旦调度器
被实例,我们就可以启动它,置它为 stand-by 模式,最后关闭它。注意:一旦一个调度器被
关闭了, 如果我们不重新实例化它, 它就不可能被再次启动。 直到调度器启动了或者当调度
器处于暂停状态,触发器才能够触发。下面有个简单的例子:
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
sched.start();
JobDetail jobDetail = new JobDetail("myJob",
null,
DumbJob.class);
Trigger trigger = TriggerUtils.makeHourlyTrigger(); // 每个小时触发
trigger.setStartTime(TriggerUtils.getEvenHourDate(new Date())); // 在下个小时开始
trigger.setName("myTrigger");
sched.scheduleJob(jobDetail, trigger);
就象你看到的,使用 Quartz 是很简单的。在下一节我们介绍 Jobs 和 Triggers 。
2.Jobs 和 Triggers
就象以前提到的,一个实现了 Job 接口的 Java类就能够被调度器执行。接口如下:
package org.quartz;
public interface Job {
public void execute(JobExecutionContext context) throws JobExecutionException;
}
很简的,当 Job 的 trigger 触发时, Job 的 execute(..)方法就会被调度器调用。被传递到
这个方法里来的 JobExecutionContext 对象提供了带有 job 运行时的信息: 执行它的调度器句
柄、触发它的触发器句柄、 job 的 JobDetail 对象和一些其他的项。
JobDetail 对象是 Job 在被加到调度器里时所创建的,它包含有很多的 Job 属性设置,和
JobDataMap 一样,可以用来存储 job 实例时的一些状态信息。
Trigger 对象是用来触发执行 Job 的。当调度一个 job 时,我们实例一个触发器然后调整它的
属性来满足 job 执行的条件。触发器也有一个和它相关的 JobDataMap,它是用来给被触发
器触发的 job 传参数的。Quartz 有一些不同的触发器类型, 不过,用得最多的是 SimpleTrigger
和 CronTrigger 。
如果我们需要在给定时刻执行一次 job 或者在给定时刻触发 job 随后间断一定时间不停
的执行的话, SimpleTrigger 是个简单的解决办法;如果我们想基于类似日历调度的触发 job
的话,比如说, 在每个星期五的中午或者在每个月第 10 天的 10:15 触发 job 时,CronTrigger
是很有用的。
为什么用 jobs 和 triggers 呢?很多任务调度器并没有任务和触发器的概念, 一些任务调度器
简单定义一个“ job”为在一个执行时间伴随一些小任务标示,其他的更像 Quartz 里 job 和
trigger 对象的联合体。在开发 Quartz 时,开发者们决定,在调度时间表和在这上面运行的
工作应该分开。这是很有用的。
例如, job 能够独立于触发器被创建和储存在任务调度器里,并且,很多的触发器能够
与同一个 job 关联起来。 这个松耦合的另一个好处就是在与 jobs 关联的触发器终止后, 我们
能够再次配置保留在调度器里的 jobs,这样的话,我们能够再次调度这些 jobs 而不需要重
新定义他们。我们也可以在不重新定义一个关联到 job 的触发器的情况下,修改或替代它。
当 Jobs和 triggers 被注册到 Quartz 的调度器里时,他们就有了唯一标示符。他们也可以被
放到“ groups”里, Groups 是用来组织分类 jobs 和 triggers 的,以便今后的维护。在一个组
里的 job 和 trigger 的名字必须是唯一的, 换句话说, 一个 job 和 trigger 的全名为他们的名字
加上组名。如果把组名置为 ”null”,系统会自动给它置为 Scheduler.DEFAULT_GROUP
现在,我们大概有了一些 jobs 和 triggers 的理解,随后 2 节我们将根多的了解它们。
3.更多关于 Jobs & JobDetails
Jobs 很容易实现, 这儿有更多我们需要理解的东西: jobs 的本质, job 接口的 execute(..)方法,
关于 JobDetails。
当我们实现的一个 class 是真正的 ”job”时, Quartz 需要知道各种 job 有的属性,这是通
过 JobDetail 类做到的。在没用 JobDetail 之前, JobDetail 的功能的实现是通过在每个 job 的
实现类上加上所有的现在 JobDetail 的 get 方法来实现的。 这就在每个 job 类上强加了一些实
现一样功能的代码,就显得每个 job 类很笨重,于是, Quartz 开发者们就创造了 JobDetail
类。
现在, 我们来讨论一下在 Quartz 里 job 的本质和 job 实例的生命周期。 首先我们来看看
第一节的代码片段:
JobDetail jobDetail = new JobDetail("myJob", // job 名称
sched.DEFAULT_GROUP, // job 组名 (可以写 'null' 来用 default group)
DumbJob.class); //要执行的 java 类
Trigger trigger = TriggerUtils.makeDailyTrigger(8, 30);
trigger.setStartTime(new Date());
trigger.setName("myTrigger");
sched.scheduleJob(jobDetail, trigger);
现在我们定义“ DumbJob ”类:
public class DumbJob implements Job {
public DumbJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException
{
System.err.println("DumbJob is executing.");
}
}
可以看到我们给调度器一个 JobDetail 实例,并且,它通过 job 的类代码引用这个 job 来执行。
每次调度器执行 job 时,它会在调用 job 的 execute(..)方法之前创建一个他的实例。 这就带来
了两个事实:一、 job 必须有一个不带参数的构造器,二、在 job 类里定义数据成员并没有
意义,因为在每次 job 执行的时候他们的值会被覆盖掉。
你可能现在想要问“我怎样给一个 job 实例提供属性 /配置?”和“在几次执行间我怎样能
跟踪 job 的状态?”这些问题的答案是一样的:用 JobDataMap- JobDetail 对象的一部分。
JobDataMap
JobDataMap 能够支持任何序列化的对象,当 job 执行时,这些对象能够在 job 实例中可用。
JobDataMap 实现了 Java Map 接口,它有一些附加的方法,这些方法用来储存和跟踪简单类
型的数据。
如下代码可以很快地给 job 增加 JobDataMap:
jobDetail.getJobDataMap().put("jobSays", "Hello World!");
jobDetail.getJobDataMap().put("myFloatValue", 3.141f);
jobDetail.getJobDataMap().put("myStateData", new ArrayList());
在 job 执行时,我们可以在 job 里通过如下代码得到 JobDataMap:
public class DumbJob implements Job {
public DumbJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException
{
String instName = context.getJobDetail().getName();
String instGroup = context.getJobDetail().getGroup();
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String jobSays = dataMap.getString("jobSays");
float myFloatValue = dataMap.getFloat("myFloatValue");
ArrayList state = (ArrayList)dataMap.get("myStateData");
state.add(new Date());
System.err.println("Instance " + instName + " of DumbJob says: " + jobSays);
}
}
如果用一个持久 JobStore(在指南 JobStore 章节讨论),我们就应该注意在 JobDataMap 里
放些什么,因为在它里面的对象将会被序列化,并且这些对象会因此产生一些
class-versioning 问题。 明显的, 标准 Java 类型应该是很安全的, 但是, 任何时候某人改变了
一个你已经序列化的实例的类的定义时, 我们就要注意不能够破坏兼容性了。 在这个方面的
进一步信息可以在 Java Developer Connection Tech Tip: Serialization In The Real World 里找
到。我们能把 JDBC-JobStore 和 JobDataMap 放到一个模式里, 在那里,只有简单类型和 String
型能被储存在 Map 里,从而消去任何以后的序列化问题。
Stateful vs. Non-Stateful Jobs
触发器也有与它们关联的 JobDataMaps。假设我们有一个储存在调度器里被多个触发器关联
的 job,然而,对于每个独立的触发器,我想提供给 job 不同的数据输入,在这个时候,
JobDataMaps 就很有用了。
在 job执行期间,JobDataMaps 能够在 JobExecutionContext 里获得。JobDataMap 融合在 Trigger
和 JobDetail 类里, JobDataMap 里面的值能够利用 key 来更新。
以下例子显示,在 job 执行期间从 JobExecutionContext 里的 JobDataMap 得到数据:
public class DumbJob implements Job {
public DumbJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException
{
String instName = context.getJobDetail().getName();
String instGroup = context.getJobDetail().getGroup();
JobDataMap dataMap = context.getJobDataMap(); // 注意:不同于以前的例子
String jobSays = dataMap.getString("jobSays");
float myFloatValue = dataMap.getFloat("myFloatValue");
ArrayList state = (ArrayList)dataMap.get("myStateData");
state.add(new Date());
System.err.println("Instance " + instName + " of DumbJob says: " + jobSays);
}
}
剩余30页未读,继续阅读
资源评论
jishuyh
- 粉丝: 0
- 资源: 7万+
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 7777端口抓包数据集
- IMG_0694.GIF
- 基于图像的三维模型重建C++源代码+文档说明(高分课程设计)
- 基于聚焦法的工件立体测量方案,根据数据进行三维重建 使用HALCON处理图像,MATLAB拟合数据+源代码+数据集+效果图
- 锄战三国村 修改:货币使用不减 v1.10(2) 原创 (中文).apk
- 基于python实现的单目双目视觉三维重建+源代码+图像图片(高分课程设计)
- 基于C+++OPENCV的全景图像拼接源码(课程设计)
- 基于Python+OpenCV对多张图片进行全景图像拼接,消除鬼影,消除裂缝+源代码+文档说明+界面截图(高分课程设计)
- 基于C++实现的全景图像拼接源码(课程设计)
- 基于SIFT特征点提取和RASIC算法实现全景图像拼接python源码+文档说明+界面截图+详细注释(95分以上课程大作业)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功