SpringMVC整合Quartz實現定時任務和Spring自帶Task定時任務
阿新 • • 發佈:2019-01-22
在java中我們常用Timer和TimerTask實現定時功能,而在JavaEE專案中可以使用Spring整合Quartz定時器、Spring的Task任務。相比於Spring自帶的任務,Quartz非常的強大,能夠實現所有想要的定時任務,包括Tomcat伺服器開始啟動,定時定點定周,叢集定時任務等等的任務,有關Quartz的介紹和時間配置網上有很多的資料,就不在累贅,下面主要介紹SpringMVC整合Quartz的實現步驟。
一、Quartz定時任務
1、引入quartz
匯入quartz.jar包,或者pom.xml 配置對應的依賴:
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>1.8.6</version> </dependency>
2、 Web.xml配置
在Web專案web.xml中配置quartz的配置檔案載入路徑:
<servlet> <servlet-name>rest</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/rest-servlet.xml, /WEB-INF/classes/pyc-spring-quartz.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
3、寫具體的定時排程的任務:
package andy.test.quartz.schedule;
/**
* @author Zhang,Tianyou
* @version:2014-12-11 下午12:00:24
*
* 一個測試的列印定時任務
*/
public class MyPrintSchedule {
public void printSomething(){
//內容就是列印一句話
System.out.println("this is andy schedule");
}
}
4、配置quartz的xml配置資訊
Quartz配置檔名字可以隨便,需和web.xml中的一致。
pyc-spring-quartz.xml配置資訊如下:
<?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-3.0.xsd">
<!-- 新增排程的任務bean 配置對應的class-->
<bean id="myPrintSchedule" class="andy.test.quartz.schedule.MyPrintSchedule" />
<!--配置排程具體執行的方法-->
<bean id="myPrintDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myPrintSchedule" />
<property name="targetMethod" value="printSomething" />
<property name="concurrent" value="false" />
</bean>
<!--配置排程執行的觸發的時間-->
<bean id="myPrintTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myPrintDetail" />
<property name="cronExpression">
<!-- 每天早上8點執行任務排程 -->
<value>0 0 8 * * ?</value>
</property>
</bean>
<!-- quartz的排程工廠 排程工廠只能有一個,多個排程任務在list中新增 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- 所有的排程列表-->
<ref local="myPrintTrigger" />
</list>
</property>
</bean>
</beans>
這樣就實現了myPrint的任務排程,執行時間是每天早上8點執行一次,列印:
this is andy schedule
這句話。
quartz的功能是非常強大的,使用也非常的簡單方便,有事需要web啟動時,執行一些初始化的任務,這是我們執行配置對應的執行排程的觸發時間就能完成。其具體實現如下:
<!--配置排程執行的觸發的時間-->
<bean id="myPrintTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myPrintDetail" />
<property name="cronExpression">
<!-- 不重複計數,只執行一次 -->
<property name="repeatCount" value="0" />
</property>
</bean>
上面的配置完成了,伺服器啟動執行的任務。只被執行一次。
二、Spring自帶的任務Task
Spring自帶的定時任務是在spring3之後支援,相比於quartz定時任務Spring相對於簡單,配置也很簡單。quartz功能比Spring Task強大,支援叢集功能。
1、在spring配置中新增task的schema
pring配置檔案頭中新增名稱空間及描述
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
//....其他
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
//.....其他
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd">
2、開啟掃描定時任務包
<context:component-scan base-package="org.andy.task" />
3、配置開啟任務
<task:annotation-driven />
如果任務比較多,可以新增任務池
<task:scheduler id="scheduler" pool-size="5" />
<task:annotation-driven executor="executor" scheduler="scheduler" />
如果定時任務很多,可以配置executor執行緒池,這裡executor的含義和java.util.concurrent.Executor是一樣的,pool-size的大小官方推薦為5~10。scheduler的pool-size是ScheduledExecutorService執行緒池
4、Spring的POJO任務類
package org.andy.task;
import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 建立時間:2016年5月12日 下午3:48:38
*
* @author andy
* @version 2.2
*/
@Component("taskJob")
public class TaskJob {
private static final Logger LOG = Logger.getLogger(TaskJob.class);
//每分鐘的10秒執行
@Scheduled(cron = "10 * * * * ?")
public void job1(){
LOG.info("hello。。。。");
}
//每10秒執行一次
@Scheduled(fixedRate = 1000 * 1)
public void job(){
LOG.info("world");
}
}
三、定時配置
spring的task和quartz的任務格式都是一樣的。
Cron表示式包括下面7個欄位並區別順序:秒0-59,分0-59,小時0-23,月內日期1-31,月1-12或者JAN-DEC,周內日期1-7或者SUN-SAT,年(可選欄位)留空或者1970-2099並且通過特殊字元表示特殊意義,具體為下:
斜線(/)字元表示增量值。例如,在秒欄位中"5/15"代表從第5秒開始,每15秒一次。
問號(?)字元和字母L字元只有在月內日期和周內日期欄位中可用。問號表示這個欄位不包含具體值。所以,如果指定月內日期,可以在周內日期欄位中插入"?",表示周內日期值無關緊要。這裡有個很蛋疼的設定,無關Quartz,而是Spring整合Quartz後,它自己加的一個約束,那就是:日期(1-31)和星期(SUN-SAT)兩者,必須有一個是問號(?),系統在啟動的時候,Spring會檢查表示式,如果不符合它的規則,就會拋異常。所以在使用的時候這個地方一定要注意,而這個在Linux上執行Cron是沒有這個限制的。
字母L字元是last的縮寫。放在月內日期欄位中,表示安排在當月最後一天執行。在周內日期欄位中,如果"L"單獨存在,就等於"7",否則代表當月內周內日期的最後一個例項。所以"0L"表示安排在當月的最後一個星期日執行。
字母(W)字元把執行安排在最靠近指定值的工作日。把"1W"放在月內日期欄位中,表示把執行安排在當月的第一個工作日內。
井號(#)字元為給定月份指定具體的工作日例項。把"MON#2"放在周內日期欄位中,表示把任務安排在當月的第二個星期一。
星號(*)字元是通配字元,表示該欄位可以接受任何可能的值、表示式例子。
例子:
"0 0 08 * * ?" 每天上午8點觸發
"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 2009-2019" 2009年至2019年的每月的最後一個星期五上午10:15觸發
"0 15 10 ? * 6#3" 每月的第三個星期五上午10:15觸發