使用spring的定時任務組件的時候,代碼如下。
@Scheduled(cron="0 5/5 * * * ?")
public void sendWeatherSMS()
{
String messageContent = messageFactory.getWeatherSMS();
//如果生成短信內容為空的話,則重試3次。
int retryTimes = 3;
while(retryTimes>=0&&isEmpty(messageContent)){
logger.error("生成天氣信息短信失敗。正在進行第"+(4-retryTimes) +"次重試");
try {
Thread.sleep(1000*(10- retryTimes));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
logger.error(e);
}
messageContent=messageFactory.getWeatherSMS();
retryTimes--;
}
String phoneNumbers = getSendWeatherInfoPhoneNum().trim();
if(!isEmpty(messageContent)){
foSendSMS.execute(phoneNumbers, messageContent);
}else{
logger.error("生成天氣信息短信失敗。");
}
System.out.println("sendWeatherSMS "+phoneNumbers+" "+ messageContent + new Date());
}
忽略掉方法中的,取得內容短信為空后最大重試3次的邏輯。在觸發改cron的表達式的時候,發現sendWeatherSMS()方法執行了3次。網上也搜了一些答案, 一開始就是說配置文件文檔,tomcat問題,感覺不科學。google一下,發現spring官方文檔提供了如下的解釋:
Make sure that you are not initializing multiple instances of the same @Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use @Configurable on bean classes which are annotated with @Scheduled and registered as regular Spring beans with the container: You would get double initialization otherwise, once through the container and once through the @Configurable aspect, with the consequence of each @Scheduled method being invoked twice.
也就是說,造成這個問題的原因在於,自己配置不當或者程序的問題,導致bean被加載了多次。因此解決的辦法就是,排除一些Task所在的bean被初始化的地方,避免bean被多次初始化。 我的解決方案是,把schedule的配置文件,單獨放到一個xml,避免被多次引用。
