最近專案中需要實現定時執行任務,例如定時計算會員的積分、呼叫第三方介面等,由於專案採用spring框架,所以這裡結合spring框架來介紹。
寫作業類別
即普通的pojo,如下:
package com.pcmall.task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TaskA { private static Logger logger = LoggerFactory.getLogger(TaskA.class); public void taskA1(){ for(int i=0;i<100;i++){ System.out.println("----A1----" + i); } } public void taskA2(){ for(int i=0;i<100;i++){ System.out.println("----A2----" + i); } } }
在spring設定檔設定特定的任務
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="taskA" class="com.pcmall.task.TaskA"></bean> <bean id="taskB" class="com.pcmall.task.TaskB"></bean> <bean id="taskJobA1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="taskA"></property> <property name="targetMethod" value="taskA1"></property> <property name="concurrent" value="false"></property> </bean> <bean id="taskJobA2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="taskA"></property> <property name="targetMethod" value="taskA2"></property> <property name="concurrent" value="false"></property> </bean> <bean id="taskJobB1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="taskB"></property> <property name="targetMethod" value="taskB1"></property> <property name="concurrent" value="false"></property> </bean> <bean id="taskJobB2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="taskB"></property> <property name="targetMethod" value="taskB2"></property> <property name="concurrent" value="false"></property> </bean> <bean id="taskA1Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="taskJobA1" /> </property> <property name="cronExpression"> <value>0 0/1 * * * ?</value> </property> </bean> <bean id="taskA2Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="taskJobA2" /> </property> <property name="cronExpression"> <value>0 0/2 * * * ?</value> </property> </bean> <bean id="taskB1Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="taskJobB1" /> </property> <property name="cronExpression"> <value>0 0/1 * * * ?</value> </property> </bean> <bean id="taskB2Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="taskJobB2" /> </property> <property name="cronExpression"> <value>0 0/2 * * * ?</value> </property> </bean> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="taskA1Trigger" /> <ref bean="taskA2Trigger" /> <ref bean="taskB1Trigger" /> <ref bean="taskB2Trigger" /> </list> </property> </bean> </beans>
5個
有多個Trigger觸發,這回帶來並發問題。在Quartz中,如果你不想並發執行一個同一個 Job,你可以實作StatefulJob,而不是Job。在Spring中如果使用 MethodInvokingJobDetailFactoryBean,可以透過設定concurrent="false"屬性來實現。
尾註
在Spring中使用Quartz而不是單獨的一個應用的好處包括:
將所有的任務調度設定放在同一個地方,是任務易於維護。
只對Job編碼,Trigger和Scheduler可以透過配置設定
可以使用Pojo Java Bean執行job,而無需實作Job介面
Cron表達式的詳細用法
欄位允許值允許的特殊字元
Cron表達式的詳細用法欄位允許值允許的特殊字元Cron表達式-59 , - * /
分0-59 , - * /小時0-23 , - * /
日期1-31 , - * ? / L W C
月份1-12 或JAN-DEC , - * ? / L W C
月份1-12 或JAN-DEC , - * ? /星期
1-7 或SUN-SAT , - * ? / L C #
年(可選)留空, 1970-2099 , - * /
"0 0 12 * * ?" 每天中午12点触发 "0 15 10 ? * *" 每天上午10:15触发 "0 15 10 * * ?" 每天上午10:15触发 "0 15 10 * * ? *" 每天上午10:15触发 "0 15 10 * * ? 2005" 2005年的每天上午10:15触发 "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 * ?" 每月15日上午10:15触发 "0 15 10 L * ?" 每月最后一日的上午10:15触发 "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发