一、定时程序过去的做法
“传统”的定时程序是我们去写个Main函数,配置脚本,然后通过crontab的配置好特定的时间来运行。定时程序的监控可以通过记录日志来知道。
这样的定时程序往往适用与每天定时去执行任务,比如报表之类的需求。
对于一些特别的需求,比如轮询去扫描数据,根据数据的状态来Update数据的时候,线程的控制就显得很重要了。
本片介绍开源框架Quartz。
二、关于Quartz
1、 开放源码项目,专注于任务调度器。
2、 提供了广泛的特性:①持久化任务;②集群;③分布式
3、 Spring支持对Quartz的集成;
核心由两个接口和两个类组成:Job和Scheduler接口,JobDetail和Trigger类。不同于JDK Timer,任务不是从实现一个Job接口的类实例开始运行,实际上Quartz在需要的时候才创建job类实例。可以使用JobDetail类来包装任务状态,并传递一个信息给Job,或在一个Job的多次执行过程之间保存信息。
三、实现我们自己的任务调度器
我的需求中,需要每隔几秒钟启动一个线程来对新插入的数据进行修改。
对于这种任务Task比较多,业务也相对复杂。
选择Quartz,可以更方便的控制线程,融入Spring,这样的定时程序非常简易。
Spring对Quartz集成与其对JDK Timer调度集成类似,你可以在配置文件中配置任务调度。仅需要在程序里加载ApplicationContext,Spring会自动启动调度器。
代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd" >
<beans>
<bean name="testQuartz" autowire="byName" class="com.test.quartz.TestQuartz"></bean>
<!--定义定时执行testQuarz 这个bean中的excute()方法-->
<bean id="excuteTast" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean=" testQuartz " />
</property>
<property name="targetMethod">
<value>excute</value>
</property>
</bean>
<bean id=" excuteCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean=" excuteTast " />
</property>
<property name="cronExpression">
<!—每20秒执行一次
<value> /20 * * * * ? </value>
<!-- 从左到右分别是:秒(0-59) 分(0-59) 时(0-23) 日期(1-31) 月份(1-12) 星期(1-7) 空格为单位的分隔符,->
</property>
</bean>
<!--管理触发器的总设置,管理我们的触发器列表,可以在bean的list中放置多个触发器。
-->
<bean autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local=" excuteCronTrigger
</list>
</property>
</bean>
需要说明几点:
1)可以通过Spring注入加载我们的任务类;
2)建立触发器。可以选择SimpleTriggerBean或CronTriggerBean类。SimpleTriggerBean缺省情况下把可重复执行次数设为无限,适合一些简单的配置。
3)创建schedulerFactory。缺省情况下,SchedulerFactoryBean创建一个StdSchedulerFactory的实例,后者创建Scheduler的实现。可以通过设置schedulerFactoryClass属性来覆盖这个行为,需要继承SchedulerFactory接口来实现你自己的版本。
上面只是一些简单的使用,同时,Quartz可以设置打火策略,可以设置运行失败后立即重新运行或者停止运行,对于一些特殊日期可以跳过;也有监听器,支持插件功能。
更深入的使用我们可以做出来以下的实现
可以通过查看任务的运行状态;
可以暂停、恢复,移除任务;
可以动态调度任务。
这种功能将为我们统一定时程序,实现定时程序可控、易维护、易扩展给我们一个更好的空间。
未完待续。