2015-11-30 106 views
8

我對Spring的@Async註釋以及如何正確使用它有疑問。比方說,我有以下方法:如何在Spring中正確使用@Async

@Async 
public void test(String param1) { 
    test2(param1, null); 
} 

@Async 
public void test2(String param1, String param2) { 
    test3(param1, param2, null); 
} 

@Async 
public void test3(String param1, String param2, String param3) { 
    // do some heavy work 
} 

我需要對所有三種方法爲它異步調用@Async還是僅夠有它test3將實際做的工作?

+0

對於我的問題沒有真正的答案,只是說'@ Async'塊會異步運行。 –

回答

3

你確實只需要一種方法。僅僅因爲在第一個@Async方法啓動一個新線程之後,它與調用方法是異步的。

但是這對你意味着,高度取決於你的例子應該說明一下:

1)所以你的情況,爲test1(String param1)@Async足夠當你曾經調用test2test3通過test1

@Async 
public void test1(String param1) { 
    test2(param1, null); 
} 

private void test2(String param1, String param2) { 
    test3(param1, param2, null); 
} 

private void test3(String param1, String param2, String param3) { 
    // do something 
} 

說明該方法2和3是私人


2)但是,如果你的例子是用於說明重載爲默認參數圖案(Method chaining的方法),則它是更復雜。那麼你需要在做真正的東西的方法上有註解。因爲您只是想以異步方式執行實際執行,而不是每個鏈接步驟執行一次異步調用。

public void test(String param1) { 
    test(param1, null); 
} 


public void test(String param1, String param2) { 
    //this invocation runs async only when real AspectJ is used 
    test(param1, param2, null); 
} 

@Async 
public void test(String param1, String param2, String param3) { 
    // do something 
} 

注意,所有方法都只是命名test(方法鏈模式)

這裏的問題是,春季(沒有真正的AspectJ負載或編譯時編織)將不會運行如果通過this調用一個異步方法!(見https://stackoverflow.com/a/22561903/280244

+0

是的,它們實際上是重載的方法,不知道爲什麼我在這裏稱它們爲test1,test2和test3 ...所以基本上,執行一些異步工作的方法(在這種情況下爲''test3'')必須公開因爲它實際上是異步的(因爲我沒有使用AspectJ)?其他人不應該打擾註釋? –

0

僅在第三種方法test3使用@Async是不夠的,因爲在本地調用的原因是對象不代理,只代理對象(從容器回升,例如使用@Autowired)具有異步調用

也期待here

2

我覺得@Ralph報道了你的擔憂。

但隨着問題的名稱是「如何使用@Async正確的春天」,我不得不提到這一點:

你應該總是改變(或至少考慮改變)默認任務執行的春天上下文或使用自定義任務執行程序。

Because:

缺省情況下,SimpleAsyncTaskExecutor將用於異步 方法調用處理。

and:

注:此實現不重用線程!請考慮使用線程池TaskExecutor實現,特別是對於執行大量短暫任務的 。