Spring Boot,计划任务,双重调用

时间:2016-07-02 18:06:32

标签: java spring spring-mvc spring-boot spring-scheduled

有一个非常标准的Spring Boot(1.3.5)应用程序。

使用@EnableScheduling启用调度(在主应用程序入口点和@Configuration带注释的类上尝试过。

使用@Scheduled方法(简单的fixedDelay计划)创建了一个简单的类。

计划任务执行两次(始终)。

从我到目前为止收集到的内容,可能是因为正在加载两个上下文,因此两次收集我的bean。 好。 那么如何修复/阻止这种双重执行,因为所有配置基本上都是隐藏的Spring Boot魔法?

框架版本:

  • Spring Boot 1.3.5
  • Spring Cloud Brixton SR1

主要应用:

   @SpringBootApplication
    @EnableDiscoveryClient
    @EnableAsync
    @EnableCircuitBreaker
    public class AlertsApplication {

    public static void main(final String[] args) {
        SpringApplication.run(AlertsApplication.class, args);
    }
}

我的任务类(HookCreateRequest列表是从application.yml引入的 - 我认为目前不相关,但如果需要,可以提供):

@ConditionalOnProperty(name = "init.runner", havingValue = "InitRunner")
@ConfigurationProperties(prefix = "webhook")
public class InitRunner /*implements CommandLineRunner*/ {

    private final List<HookCreateRequest> receivers = new ArrayList<>();

    @Autowired
    private WebHookService hookService;

    @Scheduled (fixedRate = 300000)
    public void run() throws Exception {

        getReceivers().stream().forEach(item -> {
            log.debug("Request : {}", item);
            hookService.create(item);
        });

    }

    public List<HookCreateRequest> getReceivers() {
        return receivers;
    }

}

xml配置为零。 不确定还有什么可能相关?

编辑2016/07/04

我已修改为在运行时输出计划实例(我怀疑正在创建两个不同的实例)。但是,日志似乎表明它是任务对象的SAME实例。 日志: 15:01:16.170 DEBUG - scheduled.ScheduleHookRecreation - Schedule task running: scheduled.ScheduleHookRecreation@705a651b ...task stuff happening ...first run completes, then: 15:01:39.050 DEBUG - scheduled.ScheduleHookRecreation - Schedule task running: scheduled.ScheduleHookRecreation@705a651b 所以它似乎是相同的任务实例(@705a651b)。现在为什么以甜蜜的名义会被执行两次?

编辑2016/07/05

我在带有调度方法的类中添加了@PostConstruct方法,只有一些日志记录输出。通过这样做,我可以验证@PostConstruct方法被调用两次 - 这似乎是确认bean被拾取两次,这可能意味着它被送到调度程序两次。那么如何防止这种情况呢?

1 个答案:

答案 0 :(得分:0)

出现同样的问题,在我的情况下,原因是@Scheduled注释initialDelay参数缺失 - 在应用程序启动时调用了方法。