Java Spring @Scheduled任务执行两次

我在这里有一个简单的测试方法,设置为每5秒运行一次,但是看看System.out,你可以看到它似乎在做一些奇怪的事情。

@Scheduled(cron="*/5 * * * * ?") public void testScheduledMethod() { System.out.println(new Date()+" > Running testScheduledMethod..."); } 

输出:

 Wed Jan 09 16:49:15 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:15 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:20 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:20 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:25 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:25 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:30 GMT 2013 > Running testScheduledMethod... Wed Jan 09 16:49:30 GMT 2013 > Running testScheduledMethod... 

为什么每次都运行TWICE (出现)

如果你查看文档,就会有一个明确指出这种现象的说明。

该说明在此链接的第25.5.1节下,并写着:

确保您没有在运行时初始化同一@Scheduled注释类的多个实例,除非您确实要为每个此类实例安排回调。 与此相关,请确保不对使用@Scheduled注释的bean类使用@Configurable,并将其注册为带有容器的常规Spring bean:否则将获得双初始化,一次通过容器,一次通过@Configurable方面,每个@Scheduled方法的结果被调用两次。

我知道这只是目前的建议,但我认为我们没有足够的信息来进一步诊断问题。

我知道答案!!

不要初始化您的预定两次

在你的网络日志中抢夺:

WebApplicationContext一次和servlet一次

所以在你的servlet.xml不要这样做

 import resource="classpath:applicationContext.xml" 

它是由于上下文监听器而发生的

只需删除

<听众>

org.springframework.web.context.ContextLoaderListener

从web.xml它应该工作。

我遇到过类似的问题。 可能是由于以下原因。

  1. 春季版本中的错误https://jira.spring.io/browse/SPR-10830

  2. 上下文被加载两次。

  3. log4j.xml两次写日志。 它发生在我的情况下,不确定你的。 如果您已尝试过其他选项,请尝试使用此选项。

我遇到了类似的问题,我解决了这个问题:

 package com.sample.config; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; @Configuration @EnableScheduling public class JobExecutorConfig { } 

作为弹簧靴的配置。 我将其添加为jobclass:

 package com.sample.jobs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class Job { private final Logger log = LoggerFactory.getLogger(this.getClass()); @Autowired MyOtherClass moc; @Scheduled(fixedRate = 60000) // every 60 seconds public void doJob() { log.debug("Job running !!!"); try { moc.doSomething() } catch (Exception e) { log.error(e.getMessage()); } finally { log.debug("job Done !!!"); } } // examples of other CRON expressions // * "0 0 * * * *" = the top of every hour of every day. // * "*/10 * * * * *" = every ten seconds. // * "0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day. // * "0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day. // * "0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays // * "0 0 0 25 12 ?" = every Christmas Day at midnight } 

我有同样的问题,我最终发现问题是由于在root context创建bean以及servlet context

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

这个答案真的很好地解释了如何解释我的问题。

我有同样的问题。 花了好几个小时试图解决。

解决方案是应用程序在Tomcat上部署了两次。

在尝试清理Tomcat时,它出错了。

检查server.xml Tomcat文件我注意到它被部署了两次。 还有一个未公开的“主机”标签。 不知道这些中的哪一个修复了它,但让它再次正常工作而松了一口气。

我使用的是Spring 4.0.3,我遇到了这个问题。 我通过重命名我的豆来解决它。

至:

    

我注意到一些INFO日志记录说没有找到名为taskScheduler的bean,创建了一个新实例。 所以我认为有两个taskScheduler实例。

让我知道这是否也适合你:)

在我的情况下,作业的bean有@Component注释,我在applicationContext.xml中有这个:

所以解决方案是删除bean定义(第二行),因为:

:允许在任何Spring管理的对象上检测@Async和@Scheduled注释,因此不需要定义作业的bean或者它将被调用两次。

根据这篇文章和Spring Jira,这是Spring Framework Scheduler组件中的一个错误。

如果您的应用程序是WEB,则可能需要检查是否在两个不同的上下文中扫描同一包的组件,例如applicationContext.xml,然后再检查some-servlet.xml。

  contextConfigLocation  /WEB-INF/spring/root-context.xml /WEB-INF/spring/security/spring-security.xml /WEB-INF/spring/mongo/mongo-config.xml /WEB-INF/spring/appServlet/spring-context.xml    appServlet org.springframework.web.servlet.DispatcherServlet  contextConfigLocation /WEB-INF/spring/appServlet/spring-context.xml  1  

那是我的web.xml。 因此,您可以看到“/WEB-INF/spring/appServlet/spring-context.xml”被加载两次(一次在context-param中,一次在servlet中 – > init-param)。

我遇到了同样的情况并通过这个解决了:

1)调度服务

 @Service public class SchedulerService { @Autowired @Qualifier("WorkerClass") private Worker worker; @Scheduled(cron="0/5 * * * * ?", zone="Asia/Colombo")//zone is a sample public void doSchedule() { worker.work(); } } 

2)工人阶级

 @Component("WorkerClass") public class WorkerClass implements Worker { @Override public void work() { doSomething(); } protected void doSomething() { system.out.pringln("What must I do?"); } } 

我今天遇到了同样的问题。

在我的项目中,我使用调度程序和我的Spring启动应用程序,在我的ScheduledTaks类中,我正在使用@Component注释。 但我犯了一个错误,因为@Component代表我的类的bean,而在我的Application类中,我使用代码为这个类创建了另一个bean:

 public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } @Bean public ScheduledTasks getScheduledTasks() { return new ScheduledTasks(); } } 

我只是删除了这个注释,并且调度程序可以正常工作。

按照我的代码ScheduledTasks类的示例:

 public class ScheduledTasks { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(cron = "00 14 11 * * *") public void reportCurrentTime() { log.info("The date is: {} " + dateFormat.format(new Date()) ); } } 

结果如下:

 2016-10-20 11:13:41.298 INFO 6832 --- [ main] sbcetTomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2016-10-20 11:13:41.302 INFO 6832 --- [ main] br.com.Application : Started Application in 9.257 seconds (JVM running for 9.676) 2016-10-20 11:14:00.002 INFO 6832 --- [pool-2-thread-1] br.com.scheduler.ScheduledTasks : The date is: {} 11:14:00 

我确实有同样的问题,查看我的代码,在尝试了所有这些之后,我确实发现我在2个不同的类中有两次SpringApplicationBuilder

在application.properties中,添加以下属性,该属性告诉Spring Boot Application在应用程序启动时不启动批处理作业。

 spring.batch.job.enabled=false 

我有同样的问题。 我使用基于注释的配置如下:

 @Configuration @EnableScheduling public class SchedulerConfig { @Scheduled(fixedDelay = 60 * 1000) public void scheduledJob() { // this method gets called twice... } } 

我还扩展了AbstractAnnotationConfigDispatcherServletInitializer来初始化它。

 public class SpringWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class[] getRootConfigClasses() { return new Class[] { MainConfig.class, SchedulerConfig.class }; } @Override protected Class[] getServletConfigClasses() { return new Class[] {SpringWebConfig.class}; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected Filter[] getServletFilters() { final CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter(); encodingFilter.setEncoding(CHARACTER_ENCODING); encodingFilter.setForceEncoding(true); return new Filter[] { encodingFilter }; } 

}

getRootConfigClasses()方法中删除SchedulerConfig.class对我来说getRootConfigClasses()

 @Override protected Class[] getRootConfigClasses() { return new Class[] { MainConfig.class }; } 

我希望这有帮助。