1. 程式人生 > >Spring3 Schedule Task之註解實現 (兩次起動Schedule Task 的解決方案)

Spring3 Schedule Task之註解實現 (兩次起動Schedule Task 的解決方案)

什麽 empty task 文件中 註解 work lin schedule ask

Spring3 Schedule Task之註解實現 (兩次起步Schedule Task 的解決方案)
Spring3 Schedule Task之註解實現 (兩次啟動Schedule Task 的解決方案)
在spring3 中的新引入的task 命名空間。可以部分取代 quartz 功能,配置和API更加簡單,並且支持註解方式。但是如果需要使用比較復雜的任務調度。還是建議使用quartz。


第一步:
在Spring的相關配置文件中(applicationContext.xml或者是{project_name}_servelt.xml或者是獨立的配置文件如XXX_quartz.xml)中配置並開啟Spring Schedule Task.註意其中高亮的部分是必須的。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
">
<mvc:annotation-driven />

<context:component-scan base-package="com.mytools.validator.engine" />

<!-- 啟動定時器 -->
<task:annotation-driven/>
</beans>

第二步:
可以在類中的需要定時執行的方法下指定如下Annotation
@Scheduled(cron="0 33/3 * * * ?") //每小時的33分鐘開始執行,每3分鐘執行1次
public void start() throws ServletException {
validate();
}
備註:其實@Scheduled中可以指定如下3中時間表達式:
(1)fixedRate:每隔多少毫秒執行一次該方法。如:

@Scheduled(fixedRate=2000) // 每隔2秒執行一次
public void scheduleMethod(){
System.out.println("Hello world...");
}
  (2)fixedDelay:當一次方法執行完畢之後,延遲多少毫秒再執行該方法。
 
  (3)cron:詳細配置了該方法在什麽時候執行。cron值是一個cron表達式。如:

@Scheduled(cron="0 0 0 * * SAT")
public voidarchiveOldSpittles() {
// ...
}


到指定時間後,任務總是執行2次的解決方案:
這是因為我們很容易在一個基於Spring的Web工程中啟動2個定時線程:
第一次:web容器啟動的時候,讀取applicationContext.xml(或者別的Spring核心配置文件)文件時,會加載一次。

第二次:Spring本身會加載applicationContext.xml(或者別的Spring核心配置文件)一次。

解決方案:將你的Task的相關配置獨立出來並在web.xml中通過context-param加載。而不是通過spring加載。
1) 獨立出Spring-Task,如新命名一個文件名叫cms_quartz.xml
2) 在web.xml中去加載該文件:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/cms-servlet.xml,classpath:cms-quartz.xml</param-value>
</context-param>



*********************************

1.首先加入下載spring3.2 ,http://projects.spring.io/spring-framework/

2.加入jar包,在applicationContext.xml加入聲明

-xmlns加入

[java
xmlns:task="http://www.springframework.org/schema/task"
-xsi加入
[java]
http://www.springframework.org/schema/task
[java]
http://www.springframework.org/schema/task/spring-task-3.2.xsd"

[java]
<!-- 使用Annotation自動註冊Bean,解決事物失效問題:在主容器中不掃描@Controller註解,在SpringMvc中只掃描@Controller註解。 -->
<context:component-scan base-package="com.zt49">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

任務註解

[java]
<task:annotation-driven />

3.創建一個任務類(示例)
[java]
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TestTask {

@Scheduled(cron = "0 0/1 * * * ?")
public void test(){
System.out.println("test");
}

}
啟動程序,定時任務就可以了。這個示例代表每分鐘執行一次任務。

附:cron常用表示:

CronTrigger配置格式:
格式: [秒] [分] [小時] [日] [月] [周] [年]
序號 說明 是否必填 允許填寫的值 允許的通配符
1 秒 是 0-59 , - * /
2 分 是 0-59 , - * /
3 小時 是 0-23 , - * /
4 日 是 1-31 , - * ? / L W
5 月 是 1-12 or JAN-DEC , - * /
6 周 是 1-7 or SUN-SAT , - * ? / L #
7 年 否 empty 或 1970-2099 , - * /

通配符說明:
* 表示所有值. 例如:在分的字段上設置 "*",表示每一分鐘都會觸發。
? 表示不指定值。使用的場景為不需要關心當前設置這個字段的值。例如:要在每月的10號觸發一個操作,但不關心是周幾,所以需要周位置的那個字段設置為"?" 具體設置為 0 0 0 10 * ?
- 表示區間。例如在小時上設置 "10-12",表示 10,11,12點都會觸發。
, 表示指定多個值,例如在周字段上設置 "MON,WED,FRI" 表示周一,周三和周五觸發
/ 用於遞增觸發。如在秒上面設置"5/15" 表示從5秒開始,每增15秒觸發(5,20,35,50)。 在月字段上設置‘1/3‘所示每月1號開始,每隔三天觸發一次。
L 表示最後的意思。在日字段設置上,表示當月的最後一天(依據當前月份,如果是二月還會依據是否是潤年[leap]), 在周字段上表示星期六,相當於"7"或"SAT"。如果在"L"前加上數字,則表示該數據的最後一個。例如在周字段上設置"6L"這樣的格式,則表示“本 月最後一個星期五"
W 表示離指定日期的最近那個工作日(周一至周五). 例如在日字段上設置"15W",表示離每月15號最近的那個工作日觸發。如果15號正好是周六,則找最近的周五(14號)觸發, 如果15號是周未,則找最近的下周一(16號)觸發.如果15號正好在工作日(周一至周五),則就在該天觸發。如果指定格式為 "1W",它則表示每月1號往後最近的工作日觸發。如果1號正是周六,則將在3號下周一觸發。(註,"W"前只能設置具體的數字,不允許區間"-").
小提示
‘L‘和 ‘W‘可以一組合使用。如果在日字段上設置"LW",則表示在本月的最後一個工作日觸發(一般指發工資 )
# 序號(表示每月的第幾個周幾),例如在周字段上設置"6#3"表示在每月的第三個周六.註意如果指定"#5",正好第五周沒有周六,則不會觸發該配置(用 在母親節和父親節再合適不過了)
小提示
周字段的設置,若使用英文字母是不區分大小寫的 MON 與mon相同.

常用示例:
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分每分觸發
0 0/5 14 * * ? 每天下午的 2點到2點59分(整點開始,每隔5分觸發)
0 0/5 14,18 * * ? 每天下午的 2點到2點59分(整點開始,每隔5分觸發) 每天下午的 18點到18點59分(整點開始,每隔5分觸發)
0 0-5 14 * * ? 每天下午的 2點到2點05分每分觸發
0 10,44 14 ? 3 WED 3月分每周三下午的 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 每月的第三周的星期五開始觸發
0 0 12 1/5 * ? 每月的第一個中午開始每隔5天觸發一次
0 11 11 11 11 ? 每年的11月11號 11點11分觸發

Spring3 Schedule Task之註解實現 (兩次起動Schedule Task 的解決方案)