我使用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>
答案 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 任务
也可以做类似的事情