spring 3 scheduled task running 3 times

2019-04-05 19:24发布

问题:

I have a very simple method scheduled to run every 10 seconds like this:

@Component
public class SimpleTask {

    @Scheduled(fixedRate=10000)
    public void first() {
        System.out.println("Simple Task  " + new Date());
    }
}

Config:

<task:annotation-driven executor="myExecutor" scheduler="myScheduler" />
<task:executor id="myExecutor" pool-size="5"  /> 
<task:scheduler id="myScheduler" pool-size="10"  />

My problem is that my method is being invoked 3 times every 10 seconds. It should be invoked just once. What am I doing wrong? I use Spring Source ToolSuite with SpringSource tc Server 6.

回答1:

I had this same problem. One of the causes is a bug in Spring 3.0.0. I upgraded to 3.0.5 and the repetition went down to only two.

The other cause was because my class that had the @Scheduled method was getting instantiated twice. This happened because the context config was getting loaded twice. In web.xml I was pointing my ContextLoaderListener and DispatcherServlet at the same context config file:

...
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
...

WEB-INF/applicationContext.xml is the default context config for the ContextLoaderListener. So make sure that your ContextLoaderListener and your ServletDispatcher are using different context files. I ended up creating a /WEB-INF/spring-servlet.xml without any bean definitions and it worked flawlessly.



回答2:

you are mixing annotations with configuration and I dont believe you need both

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-task-namespace

From Documentation

Note 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.



回答3:

may be you load applicationContext multiple times ?