使用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,避免被多次引用。