我在外面工作实习的时候,我们做的项目是一个日报子系统,也就是定时定点为公司生成一些报表数据还有一些数据反馈。这时候我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等。当时,我做的.net的项目,我们用的一个折中办法,就是定时把所有需要的工作列表抽出来放到一个调度库里面,然后通过多线程从任务调度表里面去取任务,进行工作。这里关键就是定时。我们的定时是怎么实现的呢?
说简单一点,我们当时是把所有报表对应的信息全部都放到一张信息表里面,里面包括报表名称,要求生成报表的时间、跨度和时间间隔,然后利用多线程实现延时,每过1分钟调用一下比对时间跟缓存里面的任务列表做核对,该工作的工作。也算是比较投机取巧吧,反正是实现了。而接触了quartz之后,我才知道这个功能实现的是多么的简单。结合我们的spring框架,说一下用spring来整合quartz来实现定时任务的过程。
一、增加所依赖的JAR包
1、增加Spring的Maven依赖
- <span style="font-size:18px;"><dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>3.0.5.RELEASE</version>
- </dependency></span>
2、增加Quartz的Maven依赖
- <span style="font-size:18px;"><dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>1.8.4</version>
- </dependency></span>
二、增加定时业务逻辑类
- <span style="font-size:18px;">public class ExpireJobTask {
- private static final Logger logger = LoggerFactory.getLogger(ExpireJobTask.class);
-
- public void doTesk() {
-
-
- }
- }</span>
ExpireJobTask业务逻辑类与一般普通的类没有任务区别,它定义的doBiz方法即为调度业务方法。
三、增加Spring配置
1、增加一个线程池
- <<span style="font-size:18px;">!-- 线程执行器配置,用于任务注册 -->
- <bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
- <property name="corePoolSize" value="10"/>
- <property name="maxPoolSize" value="100"/>
- <property name="queueCapacity" value="500"/>
- </bean></span>
2、定义业务逻辑处理类
- <span style="font-size:18px;">
- <bean id="bizObject" class="com.aboy.potak.common.toolkit.scheduling.ExpireJobTask"/>
- </span>
3、增加调度业务逻辑
- <span style="font-size:18px;">
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject" ref="bizObject"/>
- <property name="targetMethod" value="doTesk"/>
- </bean></span>
上面的配置中,我们以bizObject.doBiz方法为将要调度的业务执行逻辑。
4、增加调度触发器
- <span style="font-size:18px;"><bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail" ref="jobDetail"/>
- <property name="cronExpression" value="10 0/1 * * * ?"/>
- </bean></span>
Cron表达式“10 */1 * * * ?”意为:从第10秒开始,每1分钟执行一次。
- <span style="font-size:18px;"><bean id="taskTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
- <property name="jobDetail" ref="jobDetail"/>
- <property name="startDelay" value="10000"/>
- <property name="repeatInterval" value="60000"/>
- </bean></span>
该调度表示,延迟10秒启动,然后每隔1分钟执行一次。
5、增加调度
- <span style="font-size:18px;">
- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref bean="cronTrigger"/>
- </list>
- </property>
- <property name="taskExecutor" ref="executor"/>
- </bean></span>
triggers属性中,我们可以增加多个触发器。到此,Spring已经与Quartz完美的结合了,我们接下来的工作就是启动系统,开始调度了。
而除此之外,我们还可以使用Java.util.Timer结合java.util.TimerTask来完成这项工作,但时调度控制非常不方便,并且我们需要大量的代码。相对来说是比较繁琐吧。所以使用Quartz框架无疑是非常好的选择,并且与Spring可以非常方便的集成。
总结:
合适的就是最好的,除了以上说过的的之外,当当开源的elastic-job分布式作业调度框架也是相当出名的,也是相当的好用。据说我媳妇儿工作的广州汽车那个公司的定时任务就是应用的当当的那套框架,有时间欢迎大家跟我一块来接触一下。