东子破解的quartz7月2号找到的很好这个
1 什么是Quartz
Quartz是非常灵活的,为了实现我们的需求Quartz包含了许多可以独立或被集成使用的典型范例,同时使我们编写项目中的代码也觉得很简单自然(natural)。
Quartz是很轻量级的,只需要简单的安装或配置就可以在项目中使用;如果只是相对简单的使用实际上可以直接地使用(out-of-the-box)。
Quartz具有容错性,能够持久化所调度的作业,即在系统重启后也可以继续执行原先未完成的作业。
虽然Quartz对给定的计划可以简单地运行一些系统的处理是很适用的,但只有当我们学习如何使用Quartz去驱动我们的应用业务处理流程时,才能真正的认识到Quartz的全部潜能。
1.1 什么是Quartz-从软件控件的角度
Quartz主要程序不但能够作为独立的应用(带有RMI 接口)运行,也可以作为J2EE组件资源在J2EE应用服务器运行。
2 使用Quartz
下面是一个实例化、启动Scheduler和调度执行作业的例子:
//创建一个SchedulerFactory类的实例
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
//创建一个Scheduler类的实例
Scheduler sched = schedFact.getScheduler();
//启动上面创建的Scheduler
sched.start();
//创建一个JobDetail
JobDetail jobDetail = new JobDetail("myJob",
sched.DEFAULT_GROUP,
DumbJob.class);
//创建一个SimpleTrigger
SimpleTrigger trigger = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
new Date(),
null,
0,
0L);
//把JobDetail和SimpleTrigger所创建的各自实例关联到一个Scheduler中
sched.scheduleJob(jobDetail, trigger);
3 作业和触发器(Job&Trigger)
上面已经提及到了,我们可以使Scheduler简单地执行一个实现了Job接口的Java组件,Job接口定义如下:
package org.quartz;
public interface Job {
public void execute(JobExecutionContext context)
throws JobExecutionException;
}
3.1 标识符(Identifiers)
4 作业和作业详情(Jobs&JobDetails)
Jobs的实现相对来说比较容易,只需要理解Job的性质、Job接口中的execute(…)方法和JobDetails。
我们真正需要实现的类实际上是Job的内容,通过JobDetail类向Quartz传递有关该Job的各种属性值。
接下来介绍有关Job的性质和Job在Quartz中的生命周期,以下是前面提到的代码:
JobDetail jobDetail = new JobDetail("myJob", // job name
sched.DEFAULT_GROUP, // job group
DumbJob.class); // the java class to execute
SimpleTrigger trigger = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
new Date(),
null,
0,
0L);
sched.scheduleJob(jobDetail, trigger);
public class DumbJob implements Job {
public DumbJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException
{
System.err.println("DumbJob is executing.");
}
}
哪我们如何为Job类提供属性或配置信息呢?如何跟踪两个执行任务之间的状态呢?Quartz提供了JobDataMap来实现,JobDataMap是JobDetail对象的一部分。
在Job实例运行期间对应的JobDataMap中能够容纳任意多的对象,JobDataMap是对Java Map接口的实现,并增加一些对于原始类型存储和检索的方法。
jobDetail.getJobDataMap().put("jobSays", "Hello World!");
jobDetail.getJobDataMap().put("myFloatValue", 3.141f);
jobDetail.getJobDataMap().put("myStateData", new ArrayList());
下列是在Job执行过程中获取JobDataMap有关数据的例子:
public class DumbJob implements Job {
public DumbJob() {
}
public void execute(JobExecutionContext context) throws JobExecutionException
{
String instName = context.getJobDetail().getName();//获取Job实例的name
String instGroup = context.getJobDetail().getGroup();//获取Job实例的group
JobDataMap dataMap = context.getJobDetail().getJobDataMap();//获取JobDataMap对象
String jobSays = dataMap.getString("jobSays");//获取JobDataMap中对象jobSays的值
float myFloatValue = dataMap.getFloat("myFloatValue");//获取JobDataMap中对象myFloatValue的值
ArrayList state = (ArrayList)dataMap.get("myStateData");
state.add(new Date());//获取JobDataMap中对象myStateData的值
System.err.println("Instance " + instName + " of DumbJob says: " + jobSays);
}
4.1 有状态vs.无状态的作业(Stateful vs. Non-Stateful Jobs)
我们需要有状态Job时必须实现StatefulJob接口,而不是上面的例子中的Job接口。
4.2 作业的其他属性(Other AttributesOf Jobs)
l 持久性(Durability):如果Job是非持久性的,一旦没有活动的Trigger与之相关联时,该Job会自动从Scheduler中删除掉;
l 易挥发性(Volatility):如果Job是易挥发的,当与之相关联的Schuduler停止之后,不会通过JobStore对该Job进行保存;
l JobListener:一个Job可以被关联到一个或多个JobListener,当该Job执行时,与之关联的JobListener会得到通知;
4.3 作业接口中的execute(…)方法(The Job.execute(…) Method)
5 触发器(Triggers)
与Job相比,Trigger相对来说比较简单容易,但是要能完全的掌握使用Quartz,使其包含各种自定义的时间表选项,我们必须先知道和理解Trigger。
5.1 日历(Calendars)
Calendar可以是任何实现Calendar接口的可序列化对象,如下所示:
package org.quartz;
public interface Calendar {
public boolean isTimeIncluded(long timeStamp);
public long getNextIncludedTime(long timeStamp);
}
HolidayCalendar cal = new HolidayCalendar();
cal.addExcludedDate( someDate );
sched.addCalendar("myHolidays", cal, false);
SimpleTrigger trigger = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
new Date(),
null,
SimpleTrigger.REPEAT_INDEFINITELY,
60L * 1000L);
trigger.setCalendarName("myHolidays");
// .. schedule job with trigger
SimpleTrigger trigger2 = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
new Date(),
null,
5,
5L * 24L * 60L * 60L * 1000L);
trigger2.setCalendarName("myHolidays");
// .. schedule job with trigger2
上面代码,我们创建了两个Trigger:一个是每1分钟执行触发一次,没有次数限制;另一个是每5天执行触发一次,共执行5次触发;然而,任何在Calendar中被排除的时间段的触发执行都将被取消。
5.2 过时触发指令(MisfireInstructions)
5.3 触发器的辅助类(TriggerUtils)
5.4 触发器的监听器(TriggerListeners)
Trigger能够像Job一样,可以把监听器注册到Trigger中,实现了接口TriggerListener的对象就可以接收到Trigger触发时的通知。
6 Simple触发器(SimpleTrigger)
当我们需要在规定的时间执行一次或在规定的时间段以一定的时间间隔重复触发执行Job时,SimpleTrigger就可以满足上述要求。
SimpleTrigger有几个不同的构造方法,我们只对下面这个进行分析:
public SimpleTrigger(String name, String group, Date startTime, Date endTime, int repeatCount, long repeatInterval)
SimpleTrigger例1――创建一个在当前之后10秒钟触发的,执行一次的Trigger
long startTime = System.currentTimeMillis() + 10000L;
SimpleTrigger trigger = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
new Date(startTime),
null,
0,
0L);
SimpleTrigger例2――创建一个立即触发的,并每间隔60秒钟重复触发执行一次的Trigger
SimpleTrigger trigger = newSimpleTrigger("myTrigger",
SimpleTrigger.REPEAT_INDEFINITELY,
SimpleTrigger例3――创建一个立即触发,每间隔10秒钟重复触发执行一次,开始时间为当前,结束时间为40秒钟后的Trigger
long endTime = System.currentTimeMillis() + 40000L;
SimpleTrigger trigger = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
new Date(),
new Date(endTime),
SimpleTrigger.REPEAT_INDEFINITELY,
10L * 1000L);
SimpleTrigger例4――创建一个在2005年5月8日早上10:30触发的,每间隔30秒钟重复触发执行一次,并且重复执行5次(总共触发执行6次)的Trigger
java.util.Calendar cal = new java.util.GregorianCalendar(2005, cal.MAY, 8);
cal.set(cal.HOUR, 10);
cal.set(cal.MINUTE, 30);
cal.set(cal.SECOND, 0);
cal.set(cal.MILLISECOND, 0);
Data startTime = cal.getTime()
SimpleTrigger trigger = new SimpleTrigger("myTrigger",
sched.DEFAULT_GROUP,
startTime,
null,
5,
30L * 1000L);
6.1 Simple触发器的过时触发指令(SimpleTrigger Misfire Instructions)
SimpleTrigger有几个用于当过时触发发生时向Quartz通知如何执行的指令,这些指令作为常量定义在SimpleTrigger类中,分别如下:
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT
我们也可以使用前面讨论的Trigger.MISFIRE_INSTRUCTION_SMART_POLICY,该指令是所有Trigger的默认值。
如果使用“smart policy”,SimpleTrigger将会根据实例中的配置进行动态的选择过时触发指令,JavaDOC中的SimpleTrigger.updateAfterMisfire()方法详细解析了动态选择的内容。
7 Cron触发器(CronTrigger)
CronTrigger的功能比SimpleTrigger强大,它可以实现基于类似于日历概念的作业调度,而不是单单基于一定的时间间隔的。
使用CronTrigger,我们能够定义如下类型的日历型的Schedule:每个星期五的中午,每个周末的早上9:30,或者每周一、周三和周五的早上9:00到10:00每隔5分钟。
7.1 Cron表达式(Cron Expressions)
Cron-Expressions用于配置CronTrigger实例,Cron-Expressions是一串字符串,实际上它由六个子字符串组成,子字符串间采用空格分离,从左到右分别代表:Seconds Minutes Hours Day-of-Month Month Day-of-Week。
字符串“0 0 12 ? * WED”是一个完整的Cron-Expressions例子,它所表达的意思是:每周三早上12:00。
各个子表达式的值可以是一个范围或者列表,比如,上个例子中的Day-of-Week域的值“WED”可以用“MON-FRI”、“MON,WED,FRI”或者“MON-WED,SAT”来替代。
所有子表达式都有指定各自的取值范围,下面对Cron-Expressions的各个子表达式和取值范围进行说明:
子表达式 |
允许的值 |
允许的特殊字符 |
Seconds |
0-59 |
- * / |
Minutes |
0-59 |
- * / |
Hours |
0-23 |
- * / |
Day-of-Month |
1-31 |
- * ? / L W |
Month |
1-12或JAN-DEC |
- * / |
Day-of-Week |
1-7或SUN-SAT |
- * ? / L # |
Years(Optional) |
为空或1970-2099 |
- * / |
‘-’字符表示:值的范围,10-12在Hours域中表示为:10、11和12;
‘*’字符表示:可以为任意值,‘*’在Minutes域中表示为:每分钟;
‘/’字符表示:一个左边的数值是右边基数的递增值,‘0/15’在Seconds域中表示为:第0、15、30和45秒,‘5/15’在Seconds域中表示为:第5、20、35和50;
‘?’字符表示:没有对该域指定值,可以为任意值,不对该域进行限制,‘?’只能用在Day-of-Month和Day-of-Week域中;
表达式 |
意思 |
0 0 12 * * ? |
每天12:00执行触发 |
0 15 10 ? * * |
每天10:15执行触发 |
0 15 10 * * ? |
每天10:15执行触发 |
0 15 10 * * ? * |
每天10:15执行触发 |
0 15 10 * * ? 2005 |
2005年的每天10:15执行触发 |
0 * 14 * * ? |
每天从14:00到14:59每隔1分钟执行一次触发 |
0 0/5 14 * * ? |
每天从14:00到14:59每个5分钟执行一次触发 |
0 0/5 14,18 * * ? |
每天从14:00到14:59和18:00到18:59每隔5分钟执行一次触发 |
0 0-5 14 * * ? |
每天从14:00到14:05每隔1分钟执行一次触发 |
0 10,44 14 ? 3 WED |
3月的每个星期3的14:10和14:44分别执行一次触发 |
0 15 10 15 * ? |
每月的第15日10:15执行一次触发 |
0 15 10 L * ? |
每月最后一天的10:15执行一次触发 |
0 15 10 ? * 6L |
每月的最后一个星期5的10:15执行一次触发 |
0 15 10 ? * 2002-2005 |
2002、2003、2004、2005年的每个月的最后一个星期5的10:15执行一次触发 |
0 15 10 ? * 6#3 |
每月的第3个星期5的10:15执行一次触发 |
8 触发器的监听器和作业的监听器(TriggerListeners&JobListeners)
Listener是我们创建用于监听Scheduler中关于事件发生情况的对象,其中TriggerListener接收涉及Trigger事件的情况,JobListener接收涉及Job事件的情况。
l Trigger的事件: Trigger触发、Trigger过时触发和Trigger触发的完成。
9 调度监听器(SchedulerListeners)
有关Scheduler的事件包括:Job/Trigger的增加、Job/Trigger的删除、Scheduler中一系列严重的事件和Scheduler的关闭等事件;
SchedulerListener的创建和注册与其他类型的Listener很相似,但是它没有区分全局和非全局的情况,只要实现了org.quartz.SchedulerListener接口的对象都是。
10 作业存储(JobStores)
10.1 RAMJobStore
10.2 JDBCJobStore
如果我们应用中需要Quartz与其他事务一起运行(如:J2EE应用服务器),就需要采用JobStoreCMT的事务管理方式,这样Quartz将会让应用服务器容器管理事务;
接着我们需要向JobStore声明数据库表名的前缀,通过tablePrefix进行设置:org.quartz.jobStore.tablePrefix = QRTZ_;
11 Spring中使用Quartz进行作业调度
11.1 使用JobDetailBean
JobDetail 对象包括了运行一个job所需要的所有信息。 于是Spring提供了一个所谓的JobDetailBean使得JobDetail拥有了一个真实的,有意义的默认值。让我们来看个例子:
<bean name="exampleJob"class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>example.ExampleJob</value>
</property>
<propertyname="jobDataAsMap">
<map>
<entrykey="timeout"><value>5</value></entry>
</map>
</property>
</bean>
Job detail bean拥有所有运行job(ExampleJob)的必要信息。通过job的data map来制定timeout。Job的data map可以通过JobExecutionContext(在运行时刻传递给你)来得到, 但是JobDetailBean也把从job的data map中得到的属性映射到实际job中的属性中去。 所以,如果ExampleJob中包含一个名为timeout的属性,JobDetailBean将自动为它赋值:
package example;
public class ExampleJob extends QuartzJobBean {
private int timeout;
/**
* Setter called after the ExampleJob isinstantiated
* with the value from theJobDetailBean (5)
*/
public void setTimeout(inttimeout) {
this.timeout = timeout;
}
protected voidexecuteInternal(JobExecutionContext ctx)
throws JobExecutionException {
// do the actual work
}
}
所有Job detail bean中的一些其他的设定对你来说也是可以同样设置的.
注意:使用name和group属性,你可以修改job在哪一个组下运行和使用什么名称。 默认情况下,job的名称等于job detai bean的名称(在上面的例子中为exampleJob)。
11.2 使用MethodInvokingJobDetailFactoryBean
通常情况下,你只需要调用特定对象上的一个方法。你可以使用MethodInvokingJobDetailFactoryBean准确的做到这一点:
<bean id="methodInvokingJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<propertyname="targetObject"><refbean="exampleBusinessObject"/></property>
<propertyname="targetMethod"><value>doIt</value></property>
</bean>
上面例子将导致exampleBusinessObject中的doIt方法被调用(如下):
public class BusinessObject {
// properties and collaborators
public void doIt() {
// do the actual work
}
}
<bean id="exampleBusinessObject"class="examples.ExampleBusinessObject"/>
使用MethodInvokingJobDetailFactoryBean你不需要创建只有一行代码且只调用一个方法的job,你只需要创建真实的业务对象来包装具体的细节的对象。
默认情况下,Quartz Jobs是无状态的,可能导致jobs之间互相的影响。如果你为相同的JobDetail指定两个触发器, 很可能当第一个job完成之前,第二个job就开始了。如果JobDetail对象实现了Stateful接口,就不会发生这样的事情。 第二个job将不会在第一个job完成之前开始。为了使得jobs不并发运行,设置MethodInvokingJobDetailFactoryBean中的concurrent标记为false。
<bean id="methodInvokingJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject"><refbean="exampleBusinessObject"/></property>
<propertyname="targetMethod"><value>doIt</value></property>
</bean>
注意:默认情况下,jobs在并行的方式下运行。
11.3 使用triggers和SchedulerFactoryBean来包装任务
我们已经创建了job details,jobs。我们回顾了允许你调用特定对象上某一个方法的便捷的bean。当然我们仍需要调度这些jobs。这需要使用triggers和SchedulerFactoryBean来完成。 Quartz自带一些可供使用的triggers。Spring提供两个子类triggers,分别为CronTriggerBean和SimpleTriggerBean。
Triggers也需要被调度。Spring提供SchedulerFactoryBean来暴露一些属性来设置triggers。SchedulerFactoryBean负责调度那些实际的triggers。
两个例子:
<bean id="simpleTrigger"class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<propertyname="jobDetail">
<!-- see the example ofmethod invoking job above -->
<refbean="methodInvokingJobDetail"/>
</property>
<propertyname="startDelay">
<!-- 10 seconds -->
<value>10000</value>
</property>
<propertyname="repeatInterval">
<!-- repeat every 50 seconds-->
<value>50000</value>
</property>
</bean>
<bean id="cronTrigger"class="org.springframework.scheduling.quartz.CronTriggerBean">
<propertyname="jobDetail">
<refbean="exampleJob"/>
</property>
<propertyname="cronExpression">
<!-- run every morning at 6 am -->
<value>0 6 * *1</value>
</property>
</bean>
现在我们创建了两个triggers,其中一个开始延迟10秒以后每50秒运行一次,另一个每天早上6点钟运行。 我们需要创建一个SchedulerFactoryBean来最终实现上述的一切:
beanclass="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<propertyname="triggers">
<list>
<reflocal="cronTrigger"/>
<reflocal="simpleTrigger"/>
</list>
</property>
</bean>
更多的一些属性可以通过SchedulerFactoryBean来设置,例如job details使用的Calendars,用来订制Quartz的一些属性以及其它。可以看相应的JavaDOC(http://www.springframework.org/docs/api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html)来了解进一步的信息。
东子破解的quartz7月2号找到的很好这个相关推荐
- 10月28号安全焦点DDOS事件背后内幕串串烧
文章整理:安全焦点论坛 作者:cloudx 发布时间:2006-11-09 主题:讲述安焦被DDOS背后的故事及部分安全知识!同时奉送ASP.NET备份db日志获得webshell小知识,小小伎俩,牛 ...
- 10月28号安全焦点DDOS事件背后内幕串串烧~~
主题:讲述安焦被DDOS背后的故事及部分安全知识!同时奉送ASP.NET备份db日志获得webshell小知识,小小伎俩,牛人莫笑话俺了. 本贴纯属娱乐大众!慰安下各位fans在安焦被D 9天以来无法 ...
- 2017年6月16号课堂笔记
2017年6月16号 星期五 空气质量:中度污染~轻度污染 内容:jQuery:remove,bind,attr,on和live,同辈和父辈节点的操作, keyup/keypress/keydown, ...
- 2017年06月07号课堂笔记
2017年06月07号 晴 空气质量:中度污染->良 内容:jQuery第二节:基本选择器,层次选择器,属性选择器, 基本过滤选择器,可见性过滤选择器 备注:代课老师:李老师 一.基本选择器 1 ...
- 2017年4月21号课堂笔记
2017年4月21号 星期五 空气质量:良 内容:XML,Dom4j解析XML文件,单例 一.XML 老师代码: <?xml version="1.0" encoding=& ...
- 2017年07月03号课堂笔记
2017年07月03号 星期一 多云 空气质量:轻度污染~中度污染 内容:MySQL第四节课 in和not in:两个表的内连接:exists和not exsits的使用:all,any和some: ...
- 泰山行宫碧霞元君祠_临清市泰山行宫碧霞元君祠5月4号(农历三月三十日)举行大型泰山奶奶接驾法会...
临清是泰山奶奶的娘家,每年的四月泰山奶奶要回临清省亲 临清市道教协会定于2019年农历三月三十(5月4号星期六)于临清桑树园泰山行宫碧霞元君祠举行大型泰山奶奶迎鸾接驾庙会.届时,将有架鼓会.云龙会.狮 ...
- 2008年9月3号,星期三,晴。日日行,不怕千万里;常常做,不怕千万事。 ——《格言联璧•处事》
2008年9月3号,星期三,晴. 日日行,不怕千万里:常常做,不怕千万事. --<格言联璧•处事> 今天是我博士生涯的第59天,昨天导师对我们那个项目整体篇中技术创新部分的PPT不很满意, ...
- 2016年9月下旬校园招聘面经(美团、百度、58同城、华为、微店 11月10号更新)
以下是近些天来的面试情况,大概就面了这几家,还挺顺利的,找工作太累了,缓了两天才坚持写完了,希望能帮助到近期奋斗在一线的找工作的朋友们,加油! 美团(后台开发工程师, offer) 很喜欢美团,希望有 ...
- 7 月 24 号张小龙内部讲座《通过微信谈产品》
7 月 24 号张小龙内部讲座<通过微信谈产品>有哪些亮点? 相关问题: 张小龙 2012 年 7 月 24 日的演讲,哪些值得称道或不足? 请选择一个修改理由...1. 不构成问题,需 ...
最新文章
- 3个写进简历的京东AINLP项目实战
- codeforces水题100道 第十一题 Codeforces Round #143 (Div. 2) A. Team (brute force)
- 20145233《Java程序设计》课程总结
- 分析模式 - 度量与测绘
- Redis非阻塞I/O多路复用机制
- python判断字母数字_Python判断字符串是否为字母或者数字(浮点数)的多种方法
- python 操作mysql_Python 操作MySQL
- C++ 嵌套类与局部类
- 学会这个方法,轻松为PDF文件加密,快来码住
- 2021年系统集成项目管理工程师(软考中级)连夜整理考前重点
- 任正非的小女儿,出道了!以后会代言华为手机吗?
- 安装SVN后,更新项目没有对号等图标
- 计算机学报模板百度云,《计算机学报》论文模版.
- Spring Cloud 全家桶简介
- 2021年西式面点师(初级)考试题及西式面点师(初级)免费试题
- 自考本科英语(二)学习笔记和考试经验
- 01、java02-运算符 流程控制 方法
- android拓展笔记本,有道笔记Android版上线,拓展移动终端产品布局
- redhat linux 7.2系统安装详细过程
- 计算机名无法访问。您可能没有权限使用网络资源。请与这台服务器的管理员联系以查明您是否有访问权限。拒绝访问。
热门文章
- MindSpore21天实战营(1):基于MindSpore Lite开发目标检测的安卓APP实战
- ppt无损转图片jpg,pdf api
- 从零构建神经网络-实现异或门操作
- wireshark分析PS流格式解析详解
- 监控视频分发转发服务器性能,网络视频监控系统流媒体分发存储服务器软件设计...
- 寒假2019培训:白银莲花池-usaco2007(洛谷P2411)
- 【不读唐诗,不足以知盛世】杜甫《饮中八仙歌》
- vue3监听网页窗口关闭
- minus subtract deduct这三个单词的区别
- 2019年淘客怎么做推广之大淘客都必须知道的联盟发展方向和玩法