用java.util.timer在web工程中實現類似觸發器的機制
?
現在正在做的項目要實現一個定時出帳的觸發器, 開始打算用spring整合的quartz工具來實現(同時spring也提供了對java.util.timer的支持),
spring對quartz整合的方式,是在配置文件中通過bean的property項設置一個crontrigger表達式來實現精確的時點觸發,但是由于spring只有在啟動的時候對注入值進行讀取,這樣的話就很難實現通過運行時讀取配置參數,達到不用重啟服務即可改變出帳時間的目的,所以只好自己尋找好一點的解決方案.
?
在網上找到了,看了很受啟發,我略做了一些修改,實現了在每個月的某一天的某一個時間進行任務操作的功能.
?
代碼及注釋如下:
?
先要實現一個系統的監聽器:
/**
*?
title:?
*?
description:?
*?
copyright:?copyright?(c)chen?meng?2005
*?
company:?陳盟?
*?
*?
@author
?陳盟
*?
@version
?1.0
*?
@since
?2005-1-13?/?17:26:41
*/
package
?com.wellsoon.cttbj.vab.background;
import
?java.util.date;
import
?javax.servlet.servletcontextevent;
import
?javax.servlet.servletcontextlistener;
public
?
class
?settleaccountlistener?
implements
?servletcontextlistener?{
private
?java.util.timer?timer?
=
?
null
;
/*
?
*?@see?javax.servlet.servletcontextlistener#contextinitialized(javax.servlet.servletcontextevent)
*/
public
?
void
?contextinitialized(servletcontextevent?event)?{
date?taskrun?
=
?
null
;
//
?todo?auto-generated?method?stub
taskrun?
=
?
new
?date();
timer?
=
?
new
?java.util.timer(
true
);
event.getservletcontext().log(定時器已啟動);?
/
在這里每隔一分鐘輪詢一次出帳任務,如果任務間隔比較大的話建議把這個值設的大一點,但此設置值將間接影響可設定的觸發精度.
timer.schedule(
new
?settleaccounttask(),?
0
,?
60
*
1000
);?
/
event.getservletcontext().log(已經添加任務調度表);
}
/*
?
*?@see?javax.servlet.servletcontextlistener#contextdestroyed(javax.servlet.servletcontextevent)
*/
public
?
void
?contextdestroyed(servletcontextevent?event)?{
//
?todo?auto-generated?method?stub
timer.cancel();
event.getservletcontext().log(定時器銷毀);
}
}
接著來看settleaccounttask的實現:
/**
*?
title:?
*?
description:?
*?
copyright:?copyright?(c)chen?meng?2005
*?
company:?陳盟?
*?
*?
@author
?陳盟
*?
@version
?1.0
*?
@since
?2005-1-13?/?17:35:55
*/
package
?com.wellsoon.cttbj.vab.background;
import
?java.util.calendar;
import
?java.util.date;
import
?java.util.timertask;
public
?
class
?settleaccounttask?
extends
?timertask?{
private
?
static
?
boolean
?isrunning?
=
?
false
;
private
?
static
?
long
?dotaskmillis?
=
?
0l
;
public
?
void
?run()?{
system.out.println(dotaskmillis);?
//
下面兩個值代表每月的哪一天幾點進行實際任務操作.可以通過數據庫查詢獲得
int
?c_schedule_date?
=
?
10
;
int
?c_schedule_hour?
=
?
4
;
calendar?cal?
=
?calendar.getinstance();
//
如果任務量很大,在下次輪詢時仍在執行上次輪詢的任務,則跳過本次執行,直接錯過.
if
?(
!
isrunning)?{
//
如果當前系統時間的day_of_month和hour_of_day不滿足以下條件,則跳過實際操作.
if
?(c_schedule_date?
==
?cal.get(calendar.day_of_month)?&&?c_schedule_hour?
==
?cal.get(calendar.hour_of_day))?{
//
如果上次執行任務的時間距此次輪詢時間間隔太短,則跳過實際操作.
if
((dotaskmillis?
2
*
60
*
60
*
1000
)?
<
?cal.gettimeinmillis())?{
//
?詳細任務
isrunning?
=
?
true
;
system.out.println(執行出帳操作);
dotaskmillis?
=
?cal.gettimeinmillis();
system.out.println(dotaskmillis);
isrunning?
=
?
false
;
}
}
}?
else
?{
system.out.println(錯過);
}
}
}
最后,在web.xml中加上
<listener>
? <listener-class>
??? com.xxx.background.settleaccountlistener
? </listener-class>
</listener>
?
就可以了.
如果有更好的解決方式, 希望您回復.
posted on 2007-01-22 17:35
Lib 閱讀(2797)
評論(0) 編輯 收藏 所屬分類:
Java