Spring @Scheduled在使用注释时执行任务两次

时间:2010-05-31 10:30:41

标签: spring scheduled-tasks

我使用Spring @Scheduled注释创建了任务,但由于某种原因,它执行任务两次。我的Spring Framework版本是3.0.2。

@Service
public class ReportService {

    @Scheduled(fixedDelay=1000 * 60 * 60* 24)
    @Transactional
    public void dailyReportTask()
    {
        ... code here ...
    }

}

这是我的XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    <task:scheduler id="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="1" />
    <task:annotation-driven executor="taskExecutor"
        scheduler="taskScheduler" />
</beans>

10 个答案:

答案 0 :(得分:5)

由于上下文监听器而发生

只需删除

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

来自web.xml它应该有用。

答案 1 :(得分:2)

我遇到了同样的问题,最终我发现问题是由于root context以及servlet context中创建的bean而发生的。

因此,要解决此问题,您需要将bean的创建分离到适当的上下文中。

This answer非常好地解释了如何解决这个问题。

答案 2 :(得分:1)

根据这篇文章:http://www.vodori.com/blog/spring3scheduler.html

  

Spring 3.0.0 Release有一个bug   带有任务调度程序的Web应用程序会   最终执行预定的方法   两次。这已经解决了   Spring 3.0.1。

报告了另一个影响Version / s的错误:3.0.2 https://jira.springsource.org/browse/SPR-7216

应在Version / s中修复:3.0.3。

答案 3 :(得分:1)

我最近遇到了这个问题,这是因为我的应用程序在Tomcat中被eclipse部署了两次。问题是我在eclipse中重命名了我的应用程序,但“org.eclipse.wst.common.component”.settings文件中指定的“wb-module deploy-name”仍有旧名称。

在tomcat管理器中,我可以看到我有两个运行不同名称的应用程序。

答案 4 :(得分:0)

你实际上在哪里运行它?你的电脑?单服务器? 2个负载均衡的应用服务器?

可能是在(a)你的电脑和(b)你的服务器上运行,所以它看起来像是在运行两次,如果你看到我的意思:它正确运行一次,只是在两个不同的位置。

答案 5 :(得分:0)

检查配置文件中是否有任何手动调度程序配置(通过Java / XML)。我遇到了同样的问题,我发现我的配置正在加载我的调度程序类两次:

在Java中:

package com.mywork.br.myschuedulerpackage;
{...}
@Configuration
@EnableScheduling
public class SchedulerConfiguration {

    @Bean
    public CTXDataImporterScheduler ctxDataImporterScheduler() {
        return new CTXDataImporterScheduler();
    }
}

在XML applicationContext.xml中:

<context:component-scan base-package="com.mywork.br.myschuedulerpackage" />

在我的调度程序类中,我有@Component注释,它被组件扫描捕获并再次加载,导致@scheduler方法被执行两次。 我删除了Java配置,然后现在运行良好!

答案 6 :(得分:0)

要解决@Scheduled方法的两次处理,只需从 web.xml 中删除ContextLoaderListener(如果您使用基于web.xml的应用程序):

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

如果使用基于WebApplicationInitializer的应用程序,只需删除添加ContextLoaderListener的字符串:

package com.dropbox.shortener.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class DropboxShortenerWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);

        // (!) Delete the next string
        // container.addListener(new ContextLoaderListener(rootContext));

        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(WebConfig.class);

        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        setupCharEncodingFilter(container);
    }

    private void setupCharEncodingFilter(ServletContext container) {
        container.setInitParameter("defaultHtmlEscape", "true");

        FilterRegistration charEncodingFilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
        charEncodingFilterReg.setInitParameter("encoding", "UTF-8");
        charEncodingFilterReg.setInitParameter("forceEncoding", "true");
        charEncodingFilterReg.addMappingForUrlPatterns(null, false, "/*");
     }
}

答案 7 :(得分:0)

在bean上使用@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

答案 8 :(得分:0)

Disabling below will work.
 <!-- <listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener> -->

答案 9 :(得分:-1)

我建议的一个解决方案就是像这样做

- 在应用程序上下文中

<context:component-scan base-package="com.abc.cde.dao" />

 

在yourservlet-servlet.xml

<!-- package that had all the @Controller classes -->

我这样只在加载web.xml时才加载servlet  任务

也可以做类似的事情