Quartz学习
Quartz是OpenSymphony开源组织在Job scheduling领域的一个开源项目。
当需要完成一些定时任务的时候,很好用。
一、几个关键点
1、Job
2、JobDetail
3、Trigger
4、Scheduler
5、JobDataMap
二、Demo — (web.xml配置Listener)
三、Demo — spring配置
几个关键点
1、Job:工作(具体要实现的内容,具体的业务逻辑代码)
自己写一个业务类,implements Job 这个接口。org.quartz.Job这个接口只有一个待实现的方法:
public abstract void execute(JobExecutionContext paramJobExecutionContext) throws JobExecutionException;
在自己的业务类里边重写execute这个方法,实现实际的功能。
2、JobDetail
描述这个调度方案要执行的Job有哪些。它包含job的各种属性设置,以及用于存储job实例状态信息的JobDataMap。
3、Trigger:触发器
配置时间,任务什么时候执行。Quartz自带了各种不同类型的Trigger,最常用的主要是SimpleTrigger和CronTrigger。
SimpleTrigger主要用于一次性执行的Job(只在某个特定的时间点执行一次),或者Job在特定的时间点执行,重复执行N次,每次执行间隔T个时间单位。
CronTrigger在基于日历的调度上非常有用,如“每个星期五的正午”,或者“每月的第十天的上午10:15”等。
4、Scheduler:调度器
一个调度器可以注册多个JobDetail和Trigger。
5、JobDataMap:(参考官方文档)
每次当scheduler执行job时,在调用其execute(…)方法之前会创建该类的一个新的实例;执行完毕,对该实例的引用就被丢弃了,实例会被垃圾回收。
这样在job类中,不应该定义有状态的数据属性,因为在job的多次执行中,这些属性的值不会保留。
那么如何给job实例增加属性或配置呢?如何在job的多次执行中,跟踪job的状态呢?答案就是:JobDataMap,JobDetail对象的一部分。
JobDataMap中可以包含不限量的(序列化的)数据对象,在job实例执行的时候,可以使用其中的数据;
Demo — (web.xml配置Listener)
定义Job类,实现Job接口:
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class SmsInformJob implements Job { private static Log log = LogFactory.getLog(SmsInformJob.class); @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { // 查询短信通知设置 (实现实际需要完成的业务代码) } }
实例化 Scheduler ,并注册JobDetail和Trigger,为JobDetail指定好上面的Job:
import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.impl.StdSchedulerFactory; public class QuartzSet { private static Scheduler sched; public static void load() throws Exception { // JobDetail JobDetail jobDetail = new JobDetail("smsInformJob", Scheduler.DEFAULT_GROUP, SmsInformJob.class);
// 配置Trigger(每次 *小时10分00秒的时候触发任务) CronTrigger trigger = new CronTrigger("smsInformTrigger", "smsInfo", "0 10 * * * ?"); sched = new StdSchedulerFactory().getScheduler(); sched.scheduleJob(jobDetail, trigger); sched.start(); } // 停止 public static void stop() throws Exception { sched.shutdown(); } }
在servlet监听器中调用和停止:
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class QuartzListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent arg0) { try { QuartzSet.load(); } catch (Exception e) { e.printStackTrace(); } } @Override public void contextDestroyed(ServletContextEvent arg0) { try { QuartzSet.stop(); } catch (Exception e) { e.printStackTrace(); } } }
在web.xml中注册监听事件:
<listener><listener-class>com.qyy.demo.quartz.QuartzListener</listener-class></listener>
Demo — spring配置
在spring的配置文件中配置
(注:这里的Job可以不用 implements Job ,可以是自己写的一个普通类。执行方法也不用是execute,可以是这个Job下的任意一个方法。
只需要在JobDetail配置的的地方指定好Job类和执行方法就好了: <property name="targetMethod" value="execute"></property>)
<!-- Quartz --> <!-- Job --> <bean name="SmsInformJob" class="com.qyy.quartz.SmsInformJob" /> <!-- JobDetail --> <bean id="SmsInformJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="SmsInformJob"></property> <property name="targetMethod" value="execute"></property> <property name="concurrent" value="false"></property> </bean> <!-- Trigger --> <bean id="SmsInformTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="SmsInformJobDetail"/> <!-- 5秒后运行 --> <property name="startDelay" value="5000" /> <!-- 每隔十秒重复 --> <property name="repeatInterval" value="10000" /> </bean> <!-- Scheduler --> <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="SmsInformTrigger" /> </list> </property> </bean>