六合彩最高极限

【Quartz指南】更多关于Jobs & JobDetails

Jobs很容易实现,这儿有更多我们需要理解的东西:jobs的本质,job接口的execute(..)方法,关于JobDetails

当我们实现的一个class是真正的”job”时,Quartz需要知道各种job有的属性,这是通过JobDetail类做到的。在没用JobDetail之前,JobDetail的功能的实现是通过在每个job的实现类上加上所有?#21335;?#22312;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接口,它有一些附加的方法,这些方法用?#21019;?#23384;和跟踪简单类型的数据。

如下代码可以很快地给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里,从而消去任?#25105;?#21518;的序列化问题。

Stateful vs. Non-Stateful Jobs

触发器也有与它们关联的JobDataMaps。假设我们有一个储存在调度器里被多个触发器关联的job,然而,对于每个独立的触发器,我想提供给job不同的数据输入,在这个时候,JobDataMaps就很有用了。

在job执行期间,JobDataMaps能够在JobExecutionContext里获得。JobDataMap融合在Trigger和JobDetail类里,JobDataMap里面的?#30340;?#22815;利用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);

}

}

StatefulJob

现在,关于job状态数据的一些附加要点:一个job实例能定义为”有状态的”或者”无状态的”。无状态的jobs仅当它们在被加入到调度器里时才存储JobDataMap。这就意味着,在jobs执行期间对JobDataMap里数据的任何改变都会丢失,下次执行时job将看不到这些数据。你可能会猜到,一个有状态的job就是它的反面例子-它的JobDataMap是在每次执?#22411;阩ob后再次储存的。一个缺点就是有状态的job不能够并发执行。换句话说,如果job是有状态的,一个触发器尝?#28304;?#21457;这个已经执行了的job时,这个触发器就会等待直到这次执行结束。

用实现StatefulJob 接口来标记一个job是有状态的。

Job ‘Instances’

我们能够创建一个单独的job类,并且通过创建多个JobDetails实例在调度器里储存很多它的“实例定义”,每个都有它自己的属性集和JobDataMap ,把它们?#25216;?#20837;到调度器里。

当一个触发器触发时,与它关联的job就是通过配置在调度器上的JobFactory 来实例化的。默认的JobFactory 简单的调用在job类上的newInstance()方法,你可能想要创建自己的JobFactory实现来完成一些自?#21512;?#35201;的事情,如:拥有应用程序的IoC或者DI容器进程/初始化job实例。

job的其他属性

这儿有一个其他属性的总结,这些属性是通过JobDetail对象为一个job实例定义的。

  • 持久性– 如果一个job是?#27973;?#20037;的,一旦没有任何可用的触发器与它关联时,他就会自动得从调度器里被删除。
  • 不稳定性-如果一个job是不稳定的,他就不会在重起Quartz调度器之间持?#27809;?/li>
  • 请求?#25351;川C 如果一个job“请求?#25351;础保?#22312;调度器“硬关闭”(如:该进程崩溃,机器被关掉)时这个job还在执行,过后,当调度器再次启动时,他就会再次执行。在这种情况下,JobExecutionContext.isRecovering() 方法将会返回true.
  • Job监听器 –一个job能够有0个或者多个与它关联的监听器。当job执行时,监听器就会被通知。在监听器的更多讨论请看TriggerListeners & JobListeners

JobExecutionException

最后,我们来看看Job.execute(..)方法的一些细节。你能够从execute方法里抛出的仅有的异常类型就是JobExecutionException。因为这样,我们应该使用try-catch块包围整个execute方法内容。我们还应?#27809;?#19968;些时间看看JobExecutionException文档。当job执行发生异常时,通过设置JobExecutionException,可以?#20040;薺ob再次进入调度器或者今后不再运行。

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任?#25105;晌是?#21578;之我们,以便我们及?#26412;?#27491;。

PS?#21644;?#33616;一个微信公众号: askHarries 或者qq?#28023;?74807195,里面会分享一些资深架?#25925;?#24405;制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架?#25925;?#24517;备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog? » 【Quartz指南】更多关于Jobs & JobDetails

赞 (0)
分享到:更多 ()

评论 0

  • 邮箱 (必填)
  • 网址
六合彩最高极限