2017-06-02 470 views
3

tl; dr:您能想到任何情況下我都可以尋找哪些@Scheduled任務未在Spring Boot應用程序中執行?使用@Scheduled註釋的方法在Spring Boot應用程序中不起作用

我實現了example,它工作得很好,但是,在我正在工作的更復雜的Spring Boot應用程序中,我無法獲得@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.5.1.RELEASE

+1

什麼是MyComponent類的包?你能確保MyComponent被「挑選」由Spring初始化嗎?你可以檢查這個我創建一個默認的構造函數並添加一個日誌。或者你可以嘗試使用@ComponentScan來包含它的包 – NangSaigon

+0

該組件包含其他非計劃方法,它工作得很好。整個應用程序和其中的每個組件,真的。這只是沒有執行的預定方法。 –

+0

你配置了任何TaskExecutor嗎?如果是這樣,它的線程池可能已滿。 –

回答

2

我想我想通了。我有一個實現SmartLifecycle另一個組件,以及start()方法包含while循環,我永遠走不出的(故意,從卡夫卡流中讀取)。這基本上導致初始化被卡住,因此方法從未實際上被調度。

我可以重現與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; 
    } 

} 

如果我現在

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

它完美罰款代替start()方法。

相關問題