2013-05-27 71 views
3

我需要一個POJO方法來異步執行,所以我用@Async對它進行了註釋。我已將@EnableAsync添加到我的@Configuration類中,並添加了正確的@ComponentScan。這裏有一個小的測試用例供你運行。加載上下文後,java配置文件啓動@Async方法

public class Test { 
    public static void main(String[] args) throws InterruptedException { 
     AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
     context.register(MyConfig.class); 
     context.refresh(); 
     Object o = context.getBean(AsyncBean.class); 

     //((AsyncBean)o).doStuff(); 

     System.out.println(o); 

    } 

    @ComponentScan(basePackages = "my.package") 
    @EnableAsync 
    @Configuration 
    // @EnableScheduling 
    public static class MyConfig { 
     @Bean 
     public AsyncBean bean() throws InterruptedException { 
      AsyncBean b = new AsyncBean(); 
      return b; 
     } 
    } 

    public static class AsyncBean { 
     //@Scheduled(fixedRate = 10000L, initialDelay = 1000L) 
     @Async 
     public void doStuff() throws InterruptedException { 
      for (int i = 0; i < 5; i++) { 
       System.out.println("async loop" + i + " -> " + Thread.currentThread().getId()); 
       Thread.sleep(1000L); 
      } 
     } 
    } 
} 

上面的代碼將加載AnnotationConfigApplicationContext並退出。但是,如果我取消了對//((AsyncBean)o).doStuff();的評論,那麼它將在單獨的線程中運行。爲什麼配置完全讀取後@Async方法沒有啓動?這就是我所期望的。

我已經在上面留下了一些@Scheduled的東西,所以你可以自己試試。在@Scheduled的情況下,註釋的方法立即被觸發(在初始延遲之後)。

還有什麼我需要實現的春天知道它必須啓動我的@Async方法?

回答

9

@Async無意在加載ApplicationContext後運行。它旨在在被調用時異步運行註釋的方法。

如果你想在應用程序啓動時運行一個方法,那麼你應該使用@PostConstruct註解(在非延遲加載的bean上)。如果您需要該方法異步運行,那麼您將不得不更加棘手,因爲您同時使用了@PostConstruct@Asyncas noted in the last paragraph of 25.5.2 here)。

編輯:

@Async@Scheduled之間的差異可以不從documentation最清晰。通常,@Scheduled用於說明何時應該發生特定方法的下一次調用,並且它通常是週期性的。 @Async用於異步運行方法,也就是說,啓動後臺線程後方法會立即返回以執行方法的工作。

這個令人困惑的部分是後臺線程。他們都使用一個,但他們試圖做的事情的性質是不同的(定期後臺工作通常是非用戶交互式的,而一次性後臺工作通常由用戶發起)。

+0

是否有任何文檔更詳細地描述'@ Async'和'@ Scheduled'之間的區別? –

+0

酷豆!感謝你的回答。 –

+0

我只是偶然發現了這個答案,我得說它真的簡化了我正在爲一個項目進行修補的一些優化(異步填充緩存而不會阻止我的服務器啓動)。非常感謝你! – BSJ

相關問題