spring framework web @Scheduled 执行两次的问题

当使用Spring Framework的@Scheduled注解时,发现任务被执行两次。问题源于类被初始化两次,可能由web.xml中重复加载或tomcat/server.xml配置引起。解决方案包括删除web.xml中的重复配置,或在server.xml中将appBase设为空。
与本文相关的关键词: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次


根据博主提示,成功解决问题。在此谢谢博主。




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值