1. 程式人生 > >spring3.0基於註解的定時器以及執行兩次的解決辦法

spring3.0基於註解的定時器以及執行兩次的解決辦法

參考:

配置檔案:

1.首先要在application-context.xml裡面配置好namespace 和schema,如下:

xmlns:task="http://www.springframework.org/schema/task"

2.在application-context.xml裡面配置<task:annotation-driven/>,加下面一行就行:

<task:annotation-driven/>

<!-- The <task:annotation-driven/> element sets Spring up to automatically support
    scheduled and asynchronous methods. These methods are identified with the
    @Scheduled and @Async methods, respectively -->

例如:

    <task:executor id="executor" pool-size="5"/>
 <task:scheduler id="scheduler" pool-size="10"/>
    <task:annotation-driven executor="executor" scheduler="scheduler"/>

3.在Bean裡面的排程方法加註解@Scheduled,其中@Scheduled的attribute有三種:  

  (1)fixedRate:每隔多少毫秒執行一次該方法。如:

Java程式碼 
@Scheduled(fixedRate=2000)  
public void scheduleMethod(){  
    System.out.println("Hello world...");  
}  
     

  (2)fixedDelay:當一次方法執行完畢之後,延遲多少毫秒再執行該方法。 

  (3)cron:詳細配置了該方法在什麼時候執行。cron值是一個cron表示式。如:

Java程式碼 
@Scheduled(cron="0 0 0 * * SAT")  
public voidarchiveOldSpittles(){  
// ...  


一些cron表示式的例子:


Cron expression        What it means
0 0 10,14,16 * * ?       Every day at 10 a.m., 2 p.m., and 4 p.m.
0 0,15,30,45 * 1-30 * ?    Every 15 minutes on the first 30 days of the month
30 0 0 1 1 ? 2012       30 seconds after midnight on January 1, 2012
0 0 8-17 ? * MON-FRI     Every working hour of every business day

在spring3 中的task 名稱空間。可以部分去取代 quartz,並且支援註解方式。但是如果使用更加複雜的任務排程。還是建議是使用quartz。

  • 使用 註解來 來排程任務

注意其中的@Scheduled 標籤

配置spring的applicationContext.xml

 <task:executor id="executor" pool-size="1" />
 <task:scheduler id="scheduler" pool-size="3" />
 <!-- 定時器開關-->
 <task:annotation-driven executor="executor" scheduler="scheduler" />

最近用Spring的基於註解定時器的時候,發現到時間後,任務總是重複執行兩次,在tomcat或jboss下都如此。
打印出他們的hashcode,發現是不一樣的,也就是說,在web容器啟動的時候,重複啟了兩個定時執行緒。
研究下來發現確實會載入兩次:
第一次:web容器啟動的時候,讀取applicationContext.xml檔案時,會載入一次。
第二次:Spring本身會載入applicationContext.xml一次。
而我的定時器配置就是寫在applicationContext.xml檔案裡的。

解決辦法很簡單
先把定時器配置資訊提取出來,單獨存成一個檔案,比如applicationContext-quartz.xml
然後修改web.xml,讓web容器啟動時,可以載入該檔案

這樣quartz只會在web容器啟動時載入一次,Spring不會再載入了。