两次执行的Java春@Scheduled任务(Java Spring @Scheduled task

2019-07-18 01:16发布

我在这里有一个简单的测试方法是设定为每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...

为什么两次运行(出现)每次?

Answer 1:

如果你看一下文件,有明确召唤出这种现象的说明。

该说明是在部分25.5.1这个链接 ,并写着:

请确保您没有在运行时初始化同一@Scheduled注解类的多个实例,除非你想安排回调到每一个这样的实例。 与此相关,确保你不会在其上标注有@Scheduled并注册为普通的Spring beans与容器bean类使用@Configurable:你会得到双倍的初始化,否则,一旦通过容器,一旦通过@Configurable方面,每个@Scheduled方法的结果被调用两次。

我明白,这仅仅是建议,在这一点上,但我不认为我们有足够的信息来进一步诊断问题。



Answer 2:

我知道答案!!

不要初始化您计划的两倍

抢劫你的网络日志:

WebApplicationContext一次和servlet一次

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

import resource="classpath:applicationContext.xml"


Answer 3:

这是因为上下文侦听的发生

只是删除

<听者>

<监听级> org.springframework.web.context.ContextLoaderListener </监听级>

</听众>

从web.xml中它应该工作。



Answer 4:

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

  1. 春季版本的bug, https://jira.spring.io/browse/SPR-10830

  2. 上下文加载两次。

  3. log4j.xml文件写日志的两倍。 这事发生在我的情况不知道你的。 如果你已经尝试了其他选项,试试这个一也。



Answer 5:

我有一个类似的问题,我解决我的这样做:

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
}


Answer 6:

我有同样的问题,我最终发现,作为创建豆的结果,问题发生的root context以及在servlet context

因此,要解决这个问题,你需要将豆的创作分成适当的上下文。

这个答案解释真的很好如何处理,是什么固定我的问题。



Answer 7:

我使用弹簧4.0.3,我有这个问题。 我重新命名我的豆子解决它。

至:

<task:annotation-driven executor="taskExecutor"
    scheduler="taskScheduler" />
<task:executor id="taskExecutor" pool-size="25" />
<task:scheduler id="taskScheduler" pool-size="25" />

我注意到一些信息记录说,没有命名的TaskScheduler豆发现,创建一个新的实例。 所以我想有在的TaskScheduler两个实例。

让我知道如果这也适用于你:)



Answer 8:

那么在我的情况下作业的豆有@Component注释和我有这个在我的applicationContext.xml中:

<task:annotation-driven/> <bean id="getxxx" class="com.kitar.xxxx.jobs.RomeExample"></bean>

因此,解决办法是删除bean定义(第二行),因为:

<task:annotation-driven/>允许任何Spring管理对象上@Async和@Scheduled标注的检测,从而无需定义作业的豆或将被调用两次。



Answer 9:

根据这个职位和春天吉拉这是Spring框架计划程序组件的错误。



Answer 10:

您可能要检查,如果你在两个不同的情况下扫描组件相同的包,如果你的应用是WEB,如applicationContext.xml中,然后又有些-servlet.xml中。



Answer 11:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
         /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
    </param-value>
</context-param>
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/spring-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

这是我的web.xml。 所以,你可以看到 “/WEB-INF/spring/appServlet/spring-context.xml” 被加载两次(一次的context-param,曾经在servlet的 - >的init-PARAM)。



Answer 12:

我也面临同样的情况,并解决了这个:

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?");
    }

}


Answer 13:

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

解决方法是申请于Tomcat中部署的两倍。

当试图清理的Tomcat它给了一个错误。

检查的server.xml Tomcat的文件我发现同样正在部署的两倍。 还有一个未关闭的“主机”标签。 不知道其中的这些固定的,但欣慰地有它正常工作了。



Answer 14:

我也有同样的问题,看在我的代码和尝试之后所有的在这里,我也发现,我在2个diferents类有一个SpringApplicationBuilder两次



Answer 15:

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

@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 };
}

}

卸下SchedulerConfig.classgetRootConfigClasses()方法奏效了我。

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

我希望这有帮助。



Answer 16:

今天我有同样的问题。

在项目中,我用我的春天启动应用程序,并在我的ScheduledTaks类我用的是@Component注解调度。 但我犯了一个错误,因为@Component代表一个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();
  }
}

我只是删除此注释和调度工作percectly。

按照我的代码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] s.b.c.e.t.TomcatEmbeddedServletContainer : 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


Answer 17:

在application.properties,添加以下属性,它告诉春天引导应用程序无法启动应用程序启动的批处理作业。

spring.batch.job.enabled=false


Answer 18:

有同样的问题。

就我而言,我搬到离我@服务功能@Scheduled到新的单独的类@Component来注解,它固定我的问题



文章来源: Java Spring @Scheduled tasks executing twice