Spring 提供了几个帮助类用于在应用中做调度,包括JDK Timer类和OpenSymphony Quartz Scheduler两种.
Quartz基础
Quartz包括五种主要结构用于实现调度:
- Job接口
- JobDetail类
- Trigger 抽象类
- Scheduler接口
- SchedulerFactory 接口
Job接口表示一个作业(job)。一个作业专注做一件事。它的API非常简洁。只有一个execute方法,该方法在作业被执行时有Quartz调度。该方法有一个JobExecuteContext参数,可以通过该参数给execute()方法传递有用信息。
一些数据可以通过JobDataMap传递给作业。如果一个JobDataMap被注册到JobDetail中,就能够在作业中通过 JobExecuteContext来访问。JobDetail用来描述一个特定Job的信息。Job通过触发器(Trigger)触发。Quartz提 供了集中Trigger的实现,如SimpleTrigger和CronTrigger。SimpleTrigger类似一个简单时钟,你可以定义开始是 建,结束时间,重复次数,重复周期。CronTrigger类似Linux系统中的cron。CronTrigger的设置可以非常详细,如在每个月最后 一个周五的上午10:15执行作业。需要注意的是Trigger和Job是具名的,可以被赋值给一个组,在同一组内不能出现同名。你可以对一个组创建一个 触发器,在该组内的所有Job都将会执行。
SchedulerFactory 用于获得Scheduler实例,可以用于注册作业和触发器。
实现一个简单的实例:每十秒钟打印一次欢迎。
首先实现一个作业:
定义一个Scheduler,注册触发器和作业:
执行过后,每十秒输出[JOB] Welcome to Quartz!
Spring中的Quartz
Spring中的Quartz API位于org.springframework.scheduling.quartz包中。主要类结构包括:
- QuartzJobBean 抽象类
- JobDetailBean
- SimpleTriggerBean
- CronTriggerBean
- SchedulerFactoryBean
- MethodInvokingDetailFactoryBean
很明显对应实现Quartz中相应的接口。QuartzJob实现Job,JobDetailBean继承JobDetail。 SimpleTriggerBean和CronTriggerBean继承自相应的Trigger。 MethodInvokingJobDetailFactoryBean用于在类中调用任何对象的方法。
声明Job
JobDetailBean用于声明作业。可以为其设置作业名,以及需要的数据。
实现Job类:
还可以通过setter注入的方式注入message。
声明触发器:
声明调度器,设置Job和Trigger:
所有都设置好后,可以通过加载Context,调度器将自动执行:
使用MethodInvokingJobFactoryBean
上面的范例使用的是Quartz Job,事实上在Spring中可以使用自定义Pojo Bean,无须继承自QuartzJobBean。
首先声明一个PojoBean
对应的Pojo Bean:
声明MethodInvokingJobDetailFactoryBean:
注意
一个触发器只能触发一个Job,不过一个Job可以有多个Trigger触发,这回带来并发问题。在Quartz中,如果你不想并发执行一个同一个 Job,你可以实现StatefulJob,而不是Job。在Spring中如果使用 MethodInvokingJobDetailFactoryBean,可以通过设置concurrent="false"属性来实现。
尾注
在Spring中使用Quartz而不是单独的一个应用的好处包括:
- 将所有的任务调度设置放在同一个地方,是任务易于维护。
- 只对Job编码,Trigger和Scheduler可以通过配置设置
- 可以使用Pojo Java Bean执行job,而无需实现Job接口