与本文相关的关键词:Spring @Scheduled 执行两次的问题
使用组件:Spring framework web mvc
现象如下:使用@Scheduled标注的方法会执行两次
通过google输入关键词:spring @scheduled called twice,会显示许多人遇到相似问题。
该问题的根本原因就是包含有@Scheduled方法的类被初始化两次。
在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.
由于英文不好,只能看明白大体意思:就是不要初始化两次同一个@Scheduled标注的类。
解决思路如下:
1、在web.xml文件中重复加载相关类
首先说下web.xml这个文件,通常都包含以下节点:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/springContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>springServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/spring-beans.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springServlet</servlet-name> <url-pattern>*.html</url-pattern> <url-pattern>*.do</url-pattern> </servlet-mapping>
注意其中的两个节点:context-param和servlet>init-param,这两个节点分别对应着servletContext(适用于整个Context)和servletConfig(适用于当前servlet)
无论是在context-param中,还是在init-param中,都可以设置配置文件,如果这两个地方同时加载了任务类,可能导致上述现象出现,解决办法是删除其中一个,这也是stackOverflow等网站提出的解决办法,如http://stackoverflow.com/questions/3672289/spring-3-scheduled-task-running-3-times。
也有网友说删除
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
但实际删除后会显示错误。
我遇到的情况则与重复加载有所不同,我的文件中没有重复加载,这个路子没有测试成功。
2、tomcat/conf/server.xml配置文件
最终在国内看到这篇文章:http://nkliuliu.iteye.com/blog/816335,另外打个广告:我的目前供职的网站是http://www.ickd.cn/(该链接仅针对采集程序,实际访客请无视)
需要修改:tomcat/conf/server.xml,
<Host name="localhost" appBase="" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/semwinner" path="" reloadable="true"></Context> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/emarboxmanager" path="/admin" reloadable="true"></Context> </Host>
把appBase设置为空即可!
去除了appBase="webapps"中的webapps变成了appBase="",因为web应用程序都是放在webapps这个目录下的,如果 不把“webapps“去掉,这里会调用一次quartz的任务调度,在接下来的“<Context path”中又会调用一次quartz的任务调度,所以就重复了2次
根据博主提示,成功解决问题。在此谢谢博主。