與專案公司進行對接,接入了公司的單點登入系統,同時使用shiro進行了授權相關功能開發。因此需要將該專案相關的該公司的組織機構資訊匯入到專案資料庫中。
由於公司的組織機構處於動態變化中,該組織機構資訊的匯入不是一勞永逸的,而是需要定時更新的。也就是需要按照一定的頻率執行增量更新。
定時,看到這個詞的第一反應就是定時器timer。
於是,第一版的實現也就出來了,如下所示:
- 通過calendar設定每天執行定時任務的時間;
- 通過timer的schedule方法來啟動定時任務:schedule方法有兩個過載,乙個指定延時,乙個指定時間,這裡用的是指定時間的方法,第三個引數代表兩次任務執行之間的間隔;
- schedule方法的第乙個引數是timertask子型別,需要override它的run方法,執行的邏輯就寫在run方法中;
- 然後實現乙個servletcontextlistener***,在其contextinitialized方法中建立timermanager,從而啟動定時任務;
- web.xml中配置***;
public
class timermanager
timer timer = new timer();
syncorgtask task = new syncorgtask();
// timer.schedule(task, date, period_day);
}public date addday(date date, int num)
}
public
class
syncorgtask
extends
timertask
logger.info("end transfer into db");
} catch (exception e)
logger.info("sync org succeed");
}}
public
class
syncorgtasklistener
implements
servletcontextlistener
public
void
contextdestroyed(servletcontextevent sce)
}
com.***.listener.syncorgtasklistener
listener-class>
listener>
根據除錯需要設定我們定時任務的執行時間,然後啟動除錯。
問題出現在syncorgtask(timertask子類)中,通過spring依賴注入向該類注入了乙個執行寫入資料庫邏輯的service物件(在該service物件中啟用了事務),如下:
@autowired
private isyncorginfoservice syncorginfoservice;
但是在除錯過程中發現,該service物件為null。
問題分析如下:
- 該syncorgtask類沒有新增spring相關註解以使得該類的物件被spring管理起來,因此在該類上怎加了@component註解;
@component(value = "syncorgtask")
public
class
syncorgtask /*extends
timertask*/
經過以上處理以後,問題依然存在。
懷疑是由於定時任務導致的問題,所以嘗試通過ajax請求來呼叫該方法。在某個controller中提供相應的請求介面如下:
@autowired
private syncorgtask syncorgtask;
public string ***()
啟動服務,通過瀏覽器控制台傳送請求並進行斷點跟蹤,發現syncorgtask執行正常,且service物件正常注入。
因此問題並沒有出在syncorgtask這個類中,而是出現在timermanager中了。
給timermanager增加@component註解後依然不起作用。
此時發現對於syncorgtask的呼叫是通過如下方式進行的:
timer
timer = new
timer();
syncorgtask task = new syncorgtask();
timer.schedule(task, date, period_day);
於是問題明白了,syncorgtask是由timer在啟動的時候新建立new出來的,而不是由spring容器管理的。所以其service物件無法注入也就可以理解了。
既然syncorgtask是由timermanager自行建立導致了問題,那麼我們的解決辦法就是讓syncorgtask物件自動注入timermanager。
@autowired
private syncorgtask task;
啟動除錯,直接報錯!原因是timer.schedule的第乙個引數,也就是自動注入的這個task為null。
此處沒有再跟蹤,簡單分析就是spring容器的啟動和timer的啟動不在乙個頻道上,timer要啟動任務的時候,spring還沒有完成相關bean的管理,因此沒有完成注入。
此時問題就比較麻煩起來,通過@lazy等方式也沒有能夠解決問題。
@component(value = "syncorgtask")
public
class
syncorgtask
logger.info("end transfer into db");
} catch (exception e)
logger.info("sync org succeed");
}}
base-package="com.hdzbk.auth.task"/>
scheduler="scheduler"
mode="proxy"/>
id="scheduler"
pool-size="10"/>
後記:spring真是nb! Spring定時任務
sayhello 0 08 21 下面的表示式 0 15 10 6l 2002 2005 將在2002年到2005年的每個月的最後乙個星期五上午10點15分執行作業。你不可能用 trigger來做這些事情。你可以用兩者之中的任何乙個,但哪個跟合適則取決於你的排程需要。更多詳細介紹參考此處 關於cro...
spring 定時任務
xmlns 多加下面的內容 xmlns task 然後xsi schemalocation多加下面的內容 spring task 3.1.xsd最後是我們的task任務掃瞄註解 或者 public inte ce imytestservice component import org.springf...
Spring 定時任務
scheduled cron 0 0 1 override public synchronized void dojob throws exception 字段 允許值 允許的特殊字元 秒 0 59 分 0 59 小時 0 23 日期 1 31 l w c 月份 1 12 或者 jan dec 星期...