使用@Scheduled注释的方法在Spring Boot应用程序中不起作用

时间:2017-06-02 10:51:35

标签: java spring-boot java-8 scheduled-tasks

tl;博士:你能想到我可以找到在Spring Boot应用程序中没有执行mov ah, 2Ch int 21h mov al, dl ;hundredths mov bx, 0 wait_loop: one_hun: int 21h cmp al, dl je one_hun mov al, dl inc bx cmp bx, 50 jne wait_loop 任务的任何情况吗?

我实现了example并且它运行得很好,但是,在我正在处理的更复杂的Spring Boot应用程序中,我无法运行@Scheduled方法。

我的主要课程如下:

@Scheduled

和预定应用程序所在的组件如下所示:

package com.mypackage.myapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@SpringBootApplication
@EnableWebSecurity
@EnableScheduling
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class);
    }
}

整个应用程序显然更复杂,但基本上就是这样。不幸的是,(...) @Component public class MyComponent { private static final Logger logger = LoggerFactory.getLogger(MyComponent.class); (...) @Scheduled(fixedRate = 5000) public void myScheduledTask() { logger.info("Executing scheduled task"); (...) } } 在日志中没有出现在哪里,如果我从未调试过断点,也会出现。

正如我所说,最小的例子适用于我,但在我的应用程序中它不适用。您能想到我可以检查哪些"Executing scheduled task"任务未执行的情况吗?例如,配置可以被任何东西推翻吗?有什么可以干涉吗?

我使用的是版本@Scheduled

1 个答案:

答案 0 :(得分:2)

我想我明白了。我有另一个实现SmartLifecycle的组件,start()方法包含一个我永远不会离开的while循环(故意从Kafka流中读取)。这实际上导致初始化被卡住,因此@Scheduled方法实际上从未被安排。

我可以在while(true)的最小示例中重现它。只要我这样做,@Scheduled方法就不会被执行,当我删除while时,它就可以了。

package com.mypackage.myapp;

import java.util.concurrent.CompletableFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

@Component
public class StartLoop implements SmartLifecycle {

    private static final Logger log = LoggerFactory.getLogger(StartLoop.class);
    private static final int LAST_PHASE = Integer.MAX_VALUE;
    private boolean running;

    @Override
    public void start() {
        runMyCode();
    }

    private void runMyCode() {
        running = true;
        log.info("Starting ...");
        while (running) {
            try {
                log.info("running");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    @Override
    public void stop() {
        log.info("Stopping ...");
    }

    @Override
    public void stop(Runnable callback) {
        callback.run();
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public int getPhase() {
        return LAST_PHASE;
    }

}

如果我现在用

替换start()方法
@Override
public void start() {
    CompletableFuture.runAsync(this::runMyCode);
}

它完美无缺。