Quartz 定时任务:
学习quartz定时任务将按照以下目录进行学习:
- quartz初步
- quartz的核心概念
- quartz的体系结构
- quartz的常用API
- quartz的使用
- 配置、资源schedulerFactory
- quartz监听器
一、初步:
1.1,简介
Quartz 是 OpenSymphony 开源组织在 job scheduling 领域又一个开源项目,它可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。
quartz 是开源且具有丰富特性的“任务调度库”,能够集成与任何的java应用,小到独立的应用,大至电子商业系统。quartz 能够促进 简单或复杂的调度,以执行上十,上百,甚至上万的任务。
任务 job 被定义为标准的 java 组件,能够执行任何你想要实现的功能。quartz 调度框架包含许多企业级的特性,如JTA事务,集群的支持。
简而言之,quartz 就是基于java实现的任务调度框架,用于执行你想要的任何任务。
1.2,quartz 的运行环境
1,可以独立运行嵌入在另一个独立式应用程序
2,可以在应用程序服务器(或servlet容器)内被实例化,并且参与事务
3,可以作为一个独立的程序运行(其自己的java虚拟机内),可以通过RMI使用
4,可以被实例化,作为独立的项目集群(负载均衡和故障转移功能),用于作业的执行
1.3,quartz 用到的设计模式
- builder 设计模式
- factory 设计模式
- 组件模式
- 链式编程
二、quartz 的核心概念
2.1,任务 job
job 就是你想要实现的人物类,每一个 job 必须实现 org.quartz.job 接口,且只需要实现接口定义的 execute() 方法
2.2,触发器 trigger
trigger 为你执行任务的触发器,比如你想每天定时 3 点发送一份统计邮件,trigger 将会设置 3 点进行执行该任务。
trigger 主要包含两种 SimplerTrigger 和 CronTrigger 两种。关于两者的区别和使用场景有所不同。
2.3,调度器 scheduler
scheduler 为任务的调度器,它会将任务 job 及触发器 trigger 整合起来,负责基于 trigger 设定的时间来执行 job。
三、quartz 的体系结构
四、quartz 常用的 API
4.1 Scheduler 用于调度程序交互的主程序接口。
scheduler 调度程序-任务执行计划表,只有安排进执行计划的任务 job(通过 scheduler.scheduleJob 方法安排进行执行计划),
当它预定定义的执行时间到了的时候(任务触发 trigger),该任务才会执行。
4.2 Job
我们预先定义的希望在未来时间能将被调度程序执行的任务类,我们可以自定义。
工作任务调度接口,任务类需要实现该接口。该接口中定义 execute 方法,类似 JDK 提供的 TimeTask 类的 run 方法。在里面编写任务的业务逻辑。
Job 实例在 Quartz 中的生命周期:每次调度器执行 job 时,它在调用 execute 方法前会创建一个新的 job 实例,当调用完成之后,关联的 job 对象实例会被释放,释放的实例会被垃圾回收机制回收。
4.3 JobDetail
1. 使用 JobDetail 来定义定时任务实例,JobDetail 实例是通过 JobBuilder 类创建的。
2. JobDatail 为 job 实例提供了许多设置属性,以及 JobDataMap 成员变量属性,它用来存储特定 Job 实例的状态信息,调度器需要借助 JobDatail 对象来添加 job 实例
3. JobDatail 重要属性:name、group、jobClass、jobDataMap
4.4 JobDataMap
可以包含不限量的(序列化的)数据对象,在 job 实例执行的时候,可以使用其中的数据;JobDataMap 是 java Map 接口的一个实现,额外增加了一些便于存取基本类型的数据的方法
4.5 Trigger 触发器
Trigger 对象时用来出发执行 Job的。当调度一个 job 是,我们实例一个触发器然后调整它的属性来满足 job 执行的条件。
表名任务在什么时候会执行。定义了一个已经安排的任务将在什么时候执行的时间条件,比如每 2 秒就执行一次。
4.6 JobBuilder
用于声明一个任务实例,也可以定义关于该任务的详情比如任务名、组名,这个声明的实例将会作为一个实际执行的任务。
4.7 TriggerBuilder
触发器创建器,用于创建触发器 trigger 实例
4.8 JobListener、TriggerListener、SchedulerListener
监听器,用于对组件的监听。
五、quartz 的使用
5.1 导入 jar 包
5.2 入门案例
- 任务类
- 调度类
5.3 JobExecutionContext
- 作用
当 Scheduler 调用一个 job,将会 jobExecutionContext 传递给 Job 的execute() 方法;
job 能通过 JobExecutionContext 对象访问到 Quartz 运行时候的环境以及 job 本身的明细数据。 - 获取 JobDatail 的内容
- 获取其他内容
5.4 JobDataMap
- 作用:
在进行任务调度时,JobDataMap存储在JobExecution中,非常方便获取。
JobDataMap可以用来封装在任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。
JobDataMap 实现了 JDK 的map接口,并且添加了非常方便的方法来存储基本数据类型。
Job实现类中添加setter方法对应JobDataMap的键值,Quartz框架默认的JobFactory实现类在初始化job实例对象会自动调用这些setter方法
但是要注意覆盖问题:
- 设置参数:
JobDatail 中
Trigger 中
获取参数:
5.5 有状态的job和无状态的job
- 无状态:
默认每次执行job任务的时候,都是创建一个新的job类实例、
举例:这个时候如果想统计job的调用次数,是无法实现的。count一直输出1
- 有状态:
在HelloJob类添加@PersistJobDataAfterExecution注解,多次Job调用期间可以次有一些状态信息,即可实现count的累加。
5.6 Trigger
- 类继承结构图:
- 知识点
quartz有一些不同的触发类型,不过用的最多的是SimpleTrigger和CronTrigger。
jobKey:表示job实例的标识,触发器被触发时,该指定的job实例会被执行。
startTime:表示触发器的时间表,第一次开始被触发的时间,它的数据类型是java.util.Date。
endTime:指定触发器终止被触发的时间,它的数据类型是java.util.Data。
5.7 SimpleTrigger
-
介绍
SimpleTrigger 对于设置和使用时最为简单的一种 QuartzTrigger。
它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行n次的job所设计的。按照时间间隔,或者频率来执行。 -
代码示例:
-
注意事项:
SimpleTrigger 的属性有:开始时间,结束时间,重复次数和重复时间间隔。
重复次数属性的值可以为0,正整数,或常量 SimpleTrigger.REPEAT_INDEFINITELY
重复的时间间隔属性值必须为大于0或者长整型的正整数,以毫秒作为时间单位,当重复的时间间隔为0时,意味着与Trigger同时触发执行。
如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒钟触发一个直到指定的结束时间的Trigger,而无需去计算从开始到结束的所重复的次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性值即可。
5.8 CronTrigger
-
介绍:按照日程类触发任务
如果你需要像日历那样来触发任务,而不是像SimpleTrigger那样没隔特定的时间触发,CronTriggers 通常比SimpleTrigger 更有用,因为它是基于日历作业的调度器。 -
Cron Expressions – Cron 表达式:
Cron 表达式被用来配置 CronTrigger 实例,Cron表达式是一个由7个字表达式组成的字符串,每个子表达式都描述了一个单独的日程细节,这些子表达式用空格分隔,分别表示:1 Seconds 秒
2 minutes 分钟
3 hours 小时
4 day-of-month 月中的天
5 month 月
6 day-of-week 周中的天
7 year(optional field)年(可选的域) -
取值:
-
详细说明:
单个字表达式可以包含范围或者列表。例如:前面例子中的周中的天这个域(这里是"WED")可以被替换为“MON-FRI”,“MON,WED,FRI”或者甚至“MON-WED,SAT”。
所有的域中的值都有特定的合法范围,这些值的合法范围相当明显,例如:苗和分域的合法值为0到59,小时的合法范围是0到23,day-of-month中值得合法范围是1到31,但是需要注意不同的月份中的天数不同。月份的合法值是1到12。或者字符串JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV及DEC来表示。days-of-week可以用1到7来表示(1=星期日)或者用字符串SUN,MON,TUE,WED,THU,FRI和SAT来表示。 -
符号说明:
-
注意事项:
通常情况下:4和6是互斥的,即第4个 和 第6个,参数是互斥的。因为指定了星期,几号就不能确定了,例如执行了每周三执行一次,就不能指定是几号执行了,因为每周三是几号,这个不能确定。相反指定了几号也就不能指定星期几了。使用?号表示忽略。
-
提示:
L和W可以一起使用。(企业可用在工资计算)
#可表示月中第几个周几。(企业可用于计算母亲节和父亲节)
周字段因为字母不区分大小写,例如MON==mon
也可以利用在线工具,在线生成cron表达式 -
cron 表达式练习:
-
CronTrigger 触发器使用代码示例:
六、配置,资源SchedulerFactory
6.1,配置,资源SchedulerFactory
quartz以模块方式架构,因此,要使它运行,几个组件必须很好的咬合在一起。幸运的是,已经有一些现存的助手可以完成这些工作。
所有的scheduler实例由schedulerFachtory创建:
6.2,触发器 和 job 的关系(n-1)
trigger 对于job而言就好比一个驱动器,没有触发器来定时驱动作业,作业就无法运行,对于job而言,一个job可以对应多个trigger,但对于trigger而言,一个trigger只能对应一个job,所以一个trigger只能被指派给一个job,如果你需要一个更加复杂的触发计划,可以创建多个trigger并指派它们给同一个job。
6.3,创建方式:
6.4,StdSchedulerFactory
- 用法一:输出调度开始时间
- 用法二:启动任务调度
- 用法三:任务调度挂起,即暂停操作。
- 用法四:停止,关闭任务
6.5,DirectSchedulerFactory(了解)
6.6,quartz.properties 文件
七、quartz 监听器
7.1,简介
quartz监听器用于当任务调度中你所关注时间发生时,能够及时获取这一事件的通知。类似于执行任务过程中的邮件,短信类的提醒。quartz监听器主要有JobListener、TriggerListener、SchedulerLiener 三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。
三者的使用方法类似,在开始介绍着三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,二者的区别在于:
全局监听器能够接收到所有的job/Trigger的事件通知。
而非全局监听器只能接收到其上注册的job或Trigger的事件,不在其上注册的job或trigger则不会进行监听。
作用:
类似于 aop,这里监听器的作用是在job的方法执行前 和 执行后 都可以执行相应的方法。
7.2,JobListener
- 介绍:
- 接口方法:
- 使用代码示例:
7.3,TriggerListener
- 介绍
任务调度过程中,与触发器Trigger相关的事件包括:触发器触发,触发器未正常触发、触发器完成触发。 - 方法
- 使用代码示例
7.4,SchedulerLisener
-
介绍
SchedulerListener 会在 Scheduler 的生命周期中关键事件发生时被调用。与Scheduler 有关的事件包括:
增加一个 job/trigger,删除一个job/trigger,scheduler发生严重错误,关闭scheduler 等。 -
方法
-
使用代码示例
参考资料地址:https://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/